Spring Security OAuth2授权流程
Posted
技术标签:
【中文标题】Spring Security OAuth2授权流程【英文标题】:Spring security OAuth2 authorization process 【发布时间】:2014-05-10 23:14:03 【问题描述】:谁能告诉我我应该依次调用哪些 http GET 或 POST 方法来授权我的 apache cxf Web 服务并访问资源? 我试着打电话:
http://localhost:8080/oauth/token?client_id=client1&client_secret=client1&grant_type=password&username=client1&password=client1
我能得到的只是令牌响应:
"access_token":"7186f8b2-9bae-48b6-90c2-033a4476c0fc","token_type":"bearer","refresh_token":"d7fe8cda-812b-4b3e-9ce7-b15067e001e4","expires_in":298653
但是在我得到这个令牌之后下一步是什么?如何对用户进行身份验证并访问 url /resources/MyResource/getMyInfo 中的资源,这需要具有角色 ROLE_USER 的用户? 谢谢。
我有以下 servlet 配置:
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>
<anonymous enabled="false"/>
<http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER"/>
</http>
<http pattern="/resources/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false"/>
<intercept-url pattern="/resources/MyResource/getMyInfo" access="ROLE_USER" method="GET"/>
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<http pattern="/logout" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false"/>
<intercept-url pattern="/logout" method="GET"/>
<sec:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler"/>
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<bean id="logoutSuccessHandler" class="demo.oauth2.authentication.security.LogoutImpl">
<property name="tokenstore" ref="tokenStore"/>
</bean>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="springsec/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
</bean>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<bean id="clientDetails" class="demo.oauth2.authentication.security.ClientDetailsServiceImpl"/>
<authentication-manager id="userAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="customUserAuthenticationProvider">
</authentication-provider>
</authentication-manager>
<bean id="customUserAuthenticationProvider"
class="demo.oauth2.authentication.security.CustomUserAuthenticationProvider">
</bean>
<oauth:authorization-server user-approval-handler-ref="userApprovalHandler"
client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:authorization-code/>
<oauth:implicit/>
<oauth:refresh-token/>
<oauth:client-credentials />
<oauth:password authentication-manager-ref="authenticationManager"/>
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="springsec" token-services-ref="tokenServices"/>
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore"/>
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="accessTokenValiditySeconds" value="300000"/>
<property name="clientDetailsService" ref="clientDetails"/>
</bean>
<bean id="userApprovalHandler"
class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler">
<property name="tokenServices" ref="tokenServices" />
</bean>
<bean id="MyResource" class="demo.oauth2.authentication.resources.MyResource"/>
和web.xml:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID"
version="2.5">
<display-name>Spring Secure REST</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>demo.oauth2.authentication.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>REST Service</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
更新: 在这里找到工作示例http://software.aurorasolutions.org/how-to-oauth-2-0-with-spring-security-2/ 可能对有类似问题的人有用
【问题讨论】:
【参考方案1】:您首先需要创建一个 OAuth2AccessToken,然后您可以使用它来构建一个 OAuth2RestTemplate,然后可以使用它来执行经过身份验证的 GET、POST 调用。
以下是如何设置 OAuth2RestTemplate 的示例:
ResourceOwnerPasswordAccessTokenProvider provider = new ResourceOwnerPasswordAccessTokenProvider();
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setClientAuthenticationScheme(AuthenticationScheme.form);
resource.setAccessTokenUri("accessTokenURI");
resource.setClientId("clientId");
resource.setGrantType("password");
resource.setClientSecret("clientSecret");
resource.setUsername("userName");
resource.setPassword("password");
OAuth2AccessToken accessToken = provider.obtainAccessToken(getResource(), new DefaultAccessTokenRequest());
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(getResource(), new DefaultOAuth2ClientContext(accessToken));
【讨论】:
对不起,我在春季安全方面不是很好。您能否描述完整的过程:我需要在哪里粘贴此代码?如何在 spring-security 上下文 xml 配置中配置它?我应该使用什么 URL 来验证用户身份? 你打算如何访问你的 rest api?如果您有一个 java 客户端应用程序,那么我提供的代码是一个示例,说明如何从您的服务中获取经过身份验证的 OAuth 令牌,它使用它构建一个 OAuthRestTemplate,以便所有后续请求都与它一起传递 OAuth 令牌,该令牌应该允许它访问您受保护的资源。 如果您只想通过浏览器访问您的服务,那么您必须传递从原始请求返回的 oauth 令牌字符串以及您尝试访问的所有后续 URL。用户的身份验证在第一次调用服务以获取 oauth 令牌时完成,如果用户未成功进行身份验证,您将不会在响应中收到访问令牌。 我打算使用 2 个客户端:java spring mvc 和 .net,这就是为什么我需要所有必要的 URL 来发出 http 请求以进行身份验证和访问资源。 我在问什么时候应该只使用特定的 /oauth/authorize url?以上是关于Spring Security OAuth2授权流程的主要内容,如果未能解决你的问题,请参考以下文章
针对授权标头的Spring Security OAuth2 CORS问题
Spring Security OAuth2 - 将参数添加到授权 URL
Spring Security实现OAuth2.0授权服务 - 进阶版