使用Spring Boot構建獨立的OAuth服務器(三)

使用Spring Boot構建獨立的OAuth服務器(二) 中配置了一個獨立的OAuth服務器,這裏要對Resource,即須要保護的API進行配置,使其在被訪問的時候,能夠與OAuth服務器通訊,根據Access Token獲取相關受權信息。java

下面會分別講一下使用Spring MVC和Spring Boot這兩種框架時的配置方法。web

Spring MVCspring

  1. 在pom.xml中配置依賴項和插件
    <properties>
    		<spring.version>3.2.13.RELEASE</spring.version>
            <spring.oauth.version>2.0.0.RELEASE</spring.oauth.version>
    		<servlet.version>2.5</servlet.version>
    		<jackson.version>1.9.13</jackson.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-context</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-webmvc</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-jdbc</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-context</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-aop</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-core</artifactId>
    		    <version>${spring.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.codehaus.jackson</groupId>
    		    <artifactId>jackson-core-asl</artifactId>
    		    <version>${jackson.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.codehaus.jackson</groupId>
    		    <artifactId>jackson-mapper-asl</artifactId>
    		    <version>${jackson.version}</version>
    		</dependency>
            <dependency>
                <groupId>org.springframework.security.oauth</groupId>
                <artifactId>spring-security-oauth2</artifactId>
                <version>${spring.oauth.version}</version>
            </dependency>
    	</dependencies>
    
    	<build>
    	  <plugins>
    	    <plugin>
    	      <groupId>org.apache.tomcat.maven</groupId>
    	      <artifactId>tomcat7-maven-plugin</artifactId>
    	      <version>2.0</version>
    	      <configuration>
    	        <path>/</path>
    	        <port>8081</port>
    	      </configuration>
    	    </plugin>
    	  </plugins>
    	</build>

     

  2. 添加spring-mvc.xml,配置MVC功能
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="
    	http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans.xsd
    	http://www.springframework.org/schema/context
    	http://www.springframework.org/schema/context/spring-context.xsd">
    	
    	<context:component-scan base-package="*" />
    
        <bean
            class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <ref bean="mappingJacksonHttpMessageConverter" />
                </list>
            </property>
        </bean>
        <bean id="mappingJacksonHttpMessageConverter"
            class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>application/json; charset=UTF-8</value>
                </list>
            </property>
        </bean>
    
    </beans>

     

  3. 添加spring-security.xml,配置OAuth保護,使全部API只有角色爲ROLE_USER的用戶才能訪問,注意create-session要設置爲stateless,而且配置OAuth服務器鏈接信息(checkTokenEndpointUrl,clientId和clientSecret)
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"
    	xmlns:oauth2="http://www.springframework.org/schema/security/oauth2"
    	xsi:schemaLocation="
    	http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans.xsd
    	http://www.springframework.org/schema/security   
    	http://www.springframework.org/schema/security/spring-security.xsd
    	http://www.springframework.org/schema/security/oauth2 
    	http://www.springframework.org/schema/security/spring-security-oauth2.xsd">
    	
    	<security:http pattern="/**" entry-point-ref="oauth2AuthenticationEntryPoint" use-expressions="true" create-session="stateless">
    		<security:intercept-url pattern="/*" access="hasAuthority('ROLE_USER')" />
    		<security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    	</security:http>
    
    	<oauth2:resource-server id="resourceServerFilter" token-services-ref="remoteTokenServices" />
    	
    	<security:authentication-manager />
    	
    	<bean id="remoteTokenServices" class="org.springframework.security.oauth2.provider.token.RemoteTokenServices">
    		<property name="checkTokenEndpointUrl" value="http://localhost:8080/oauth/check_token" />
    		<property name="clientId" value="client1" />
    		<property name="clientSecret" value="secret1" />
    	</bean>
    
    	<bean id="oauth2AuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint" />
    
    </beans>

     

  4. 編寫受保護的Controller,返回結果爲用戶名
    @Controller
    public class AuthorizedController {
    
        @RequestMapping(value = "/user", produces = "application/json; charset=UTF-8")
        @ResponseBody
        public Map<String, Object> user(Authentication auth) {
            Map<String, Object> result = new HashMap<String, Object>();
            result.put("username", auth.getPrincipal());
            return result;
        }
    
    }

     

Spring Bootexpress

  1. 在pom.xml中配置依賴項和插件
    <dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.security.oauth</groupId>
    			<artifactId>spring-security-oauth2</artifactId>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>

     

  2. 在application.properties中配置OAuth服務器信息(security.oauth2.resource.token-info-uri,security.oauth2.client.client-id和security.oauth2.client.client-secret)
    server.port=8081
    
    security.oauth2.resource.token-info-uri=http://localhost:8080/oauth/check_token
    security.oauth2.client.client-id=client1
    security.oauth2.client.client-secret=secret1

     

  3. 編寫主類Application,啓用Resource服務器功能
    @SpringBootApplication
    @EnableResourceServer
    public class Application {
    
    	public static void main(String[] args) {
    		SpringApplication.run(Application.class, args);
    	}
    
    }

     

  4. 編寫Resource服務器配置類,使全部API只有角色爲ROLE_USER的用戶才能訪問
    @Configuration
    public class ResourceConfig extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/**").authorizeRequests().anyRequest().access("hasAuthority('ROLE_USER')");
        }
    
    }

     

測試方法apache

  1. 啓動OAuth服務器
  2. 使用Maven運行Goal:Spring MVC爲clean compile tomcat7:run,Spring Boot爲clean spring-boot:run
  3. 直接訪問http://127.0.0.1:8081/user,會獲得以下結果
    {
        "error": "unauthorized",
        "error_description": "Full authentication is required to access this resource"
    }

     

  4. 攜帶Access Token去訪問http://127.0.0.1:8081/user,會獲得以下結果,其中user就是申請Access Token時使用的用戶名
    {
        "username": "user"
    }

攜帶Access Token的方法有兩種,第一種是使用名爲access_token的參數傳遞過去,如http://127.0.0.1:8081/user?access_token=#ACCESS_TOKEN#,第二種是使用名爲Authorization的Header傳遞過去,Header值的格式爲Bearer #ACCESS_TOKEN#,基於安全考慮,推薦使用第二種json

注意spring-mvc

使用Spring MVC時,create-session必定要設置爲stateless,不然,在第一次訪問成功後,短期內再訪問的時候若是不攜帶Access Token的話也能訪問成功,緣由是Spring Security會在第一次訪問成功後建立一個session來存儲受權信息,而使用Spring Boot則沒有這個問題tomcat

相關文章
相關標籤/搜索