在 使用Spring Boot構建獨立的OAuth服務器(二) 中配置了一個獨立的OAuth服務器,這裏要對Resource,即須要保護的API進行配置,使其在被訪問的時候,能夠與OAuth服務器通訊,根據Access Token獲取相關受權信息。java
下面會分別講一下使用Spring MVC和Spring Boot這兩種框架時的配置方法。web
Spring MVCspring
<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>
<?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>
<?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>
@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
<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>
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
@SpringBootApplication @EnableResourceServer public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@Configuration public class ResourceConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.antMatcher("/**").authorizeRequests().anyRequest().access("hasAuthority('ROLE_USER')"); } }
測試方法apache
{ "error": "unauthorized", "error_description": "Full authentication is required to access this resource" }
{ "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