(1)Third-party application:第三方运用程序,本文中又称\"大众客户端\公众(client),即上一节例子中的\"大众云冲印\"大众。
(2)HTTP service:HTTP做事供应商,本文中简称\"大众做事供应商\"大众,即上一节例子中的Google。
(3)Resource Owner:资源所有者,本文中又称\公众用户\公众(user)。
(4)User Agent:用户代理,本文中便是指浏览器。
(5)Authorization server:认证做事器,即做事供应商专门用来处理认证的做事器。
(6)Resource server:资源做事器,即做事供应商存放用户天生的资源的做事器。它与认证做事器,可以是同一台做事器,也可以是不同的做事器。
运行流程:
(1)用户打开客户端往后,客户端哀求用户授权。
(2)用户赞许给予客户端授权。
(3)客户端根据得到的授权,向认证做事器申请令牌。
(4)认证做事器对客户端进行认证,确认无误后发放令牌。
(5)客户端利用令牌,向资源做事器申请获取资源。
(6)资源做事器确认令牌无误后,向客户端开放资源。
客户真个授权模式:
授权码模式(authorization code):功能最完全、流程最严密的授权模式。它的特点便是通过客户真个后台做事器,与\公众做事供应商\"大众的认证做事器进行互动。
(1)用户访问客户端,客户端将用户导向认证做事器
客户端申请认证的URI包含以下参数:
response_type:表示授权类型,必选项,此处的值固定为\"大众code\"大众
client_id:表示客户真个ID,必选项
redirect_uri:表示重定向URI,可选项
scope:表示申请的权限范围,可选项
state:表示客户真个当前状态,可以指定任意值,认证做事器会原封不动地返回这个值。
例如:/authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
(2)用户选择是否给予客户端授权
(3)假设用户给予授权,认证做事器会将用户导向客户端原来指定的重定向URI,并加上一个授权码
做事器回应客户真个URI包含以下参数:
code:表示授权码,必选项。该码的有效期该当很短,常日设为10分钟,客户端只能利用该码一次,否则会被授权做事器谢绝。
该码与客户端ID和重定向URI,是逐一对应关系。
state:如果客户真个要求中包含这个参数,认证做事器的回应也必须千篇一律包含这个参数。
例如:https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
(4)客户端吸收到授权码和原来的重定向URI,向认证做事器申请令牌
客户端向认证做事器申请令牌的HTTP要求包含以下参数:
grant_type:表示利用的授权模式,必选项,此处的值固定为\公众authorization_code\"大众。
code:表示上一步得到的授权码,必选项。
redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持同等。
client_id:表示客户端ID,必选项。
例如:grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
(5)认证做事器核对令牌和重定向URI,确认无误后向客户端发送访问令牌和更新令牌
认证做事器发送的HTTP回答,包含以下参数:
access_token:表示访问令牌,必选项。
token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
expires_in:表示过期韶光,单位为秒。如果省略该参数,必须其他办法设置过期韶光。
refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
scope:表示权限范围,如果与客户端申请的范围同等,此项可省略。
例如:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
\"大众access_token\"大众:\"大众2YotnFZFEjr1zCsicMWpAA\"大众,
\"大众token_type\公众:\"大众example\"大众,
\公众expires_in\"大众:3600,
\"大众refresh_token\公众:\"大众tGzv3JOkF0XG5Qx2TlKWIA\"大众,
\"大众example_parameter\公众:\"大众example_value\"大众
}
从上面回答代码可以看出,干系参数利用JSON格式发送(Content-Type: application/json)。此外,HTTP头信息中明确指定不得缓存。
简化模式(implicit grant type):
spring security与OAuth2.0集成
1)修正web.xml文件:
<!-- filter代理,通过spring容器来管理filter的生命周期 -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
2)配置applicationContext-security.xml:
<!-- 添加http拦截链 -->
<!-- /oauth/token是oauth2上岸验证要求的url,用于获取access_token,默认的生存韶光是43200秒,即12小时 -->
<http pattern=\公众/oauth/token\公众 create-session=\"大众stateless\"大众
authentication-manager-ref=\"大众oauth2AuthenticationManager\"大众
entry-point-ref=\"大众oauth2AuthenticationEntryPoint\"大众>
<!-- 设置拦截地址和规则 -->
<intercept-url pattern=\公众/oauth/token\"大众 access=\"大众isAuthenticated()\"大众 />
<csrf disabled=\公众true\"大众/>
<!-- 非匿名 -->
<anonymous enabled=\"大众false\"大众 />
<http-basic entry-point-ref=\公众oauth2AuthenticationEntryPoint\"大众 />
<!-- 设置过滤链 -->
<custom-filter ref=\公众clientCredentialsTokenEndpointFilter\"大众 before=\公众BASIC_AUTH_FILTER\"大众 />
<!-- 谢绝访问处理 -->
<access-denied-handler ref=\公众oauth2AccessDeniedHandler\公众 />
</http>
<!-- token仓库:将token信息存放数据库,须要dataSource工具(也可以存储在内存中InMemoryTokenStore) -->
<beans:bean id=\"大众tokenStore\公众
class=\"大众org.springframework.security.oauth2.provider.token.store.JdbcTokenStore\公众>
<beans:constructor-arg index=\"大众0\"大众 ref=\公众dataSourceSys\"大众 />
</beans:bean>
<!-- 用于天生访问令牌token:如果许可刷新token,请将supportRefreshToken 的值设置为true, 默认为不许可-->
<beans:bean id=\"大众tokenServices\"大众 class=\"大众org.springframework.security.oauth2.provider.token.DefaultTokenServices\公众>
<beans:property name=\"大众tokenStore\"大众 ref=\公众tokenStore\"大众 />
<beans:property name=\"大众supportRefreshToken\"大众 value=\"大众true\"大众 />
</beans:bean>
<!-- ClientDetailsService 配置, 利用JdbcClientDetailsService,oauth2客户端数据库操作类 -->
<beans:bean id=\"大众clientDetailsService\"大众
class=\公众org.springframework.security.oauth2.provider.client.JdbcClientDetailsService\"大众>
<beans:constructor-arg index=\公众0\"大众 ref=\"大众dataSourceSys\"大众 />
</beans:bean>
<!-- ClientDetailsUserDetailsService配置:该类实现了Spring security中 UserDetailsService 接口 -->
<beans:bean id=\"大众oauth2ClientDetailsUserService\"大众
class=\"大众org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService\公众>
<beans:constructor-arg ref=\"大众clientDetailsService\公众 />
</beans:bean>
<!-- Oauth2 认证管理器:用来区分客户端用户-->
<authentication-manager id=\"大众oauth2AuthenticationManager\"大众>
<authentication-provider user-service-ref=\"大众oauth2ClientDetailsUserService\公众 />
</authentication-manager>
<!-- 自定义oauth2认证缺点信息处理类 -->
<beans:bean id=\"大众headerOnlyExceptionRender\"大众 class=\"大众com.spsoft.tms.security.oauth2.HeaderOnlyOAuth2ExceptionRenderer\"大众 />
<!-- Oauth2身份验证失落败处理类(认证点) -->
<beans:bean id=\"大众oauth2AuthenticationEntryPoint\"大众
class=\公众org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint\"大众>
<beans:property name=\"大众exceptionRenderer\"大众 ref=\公众headerOnlyExceptionRender\"大众 />
</beans:bean>
<!-- oauth2访问谢绝 -->
<beans:bean id=\公众oauth2AccessDeniedHandler\公众
class=\"大众org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler\公众>
<beans:property name=\公众exceptionRenderer\"大众 ref=\"大众headerOnlyExceptionRender\"大众 />
</beans:bean>
<!-- oauth2访问成功,保存用户授权运用信息 -->
<beans:bean id=\公众oauthUserApprovalHandler\公众
class=\"大众org.springframework.security.oauth2.provider.approval.ApprovalStoreUserApprovalHandler\"大众>
<beans:property name=\"大众approvalStore\"大众 ref=\"大众approvalStore\"大众 />
<beans:property name=\公众requestFactory\"大众 ref=\"大众oauth2RequestFactory\公众 />
</beans:bean>
<!-- 记录用户授权信息 -->
<beans:bean id=\"大众approvalStore\"大众
class=\公众org.springframework.security.oauth2.provider.approval.JdbcApprovalStore\"大众>
<beans:constructor-arg index=\公众0\公众 ref=\"大众dataSourceSys\公众 />
</beans:bean>
<!-- oauth2要求工厂类,紧张用于天生Oauth要求工具 -->
<beans:bean id=\公众oauth2RequestFactory\"大众
class=\"大众org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory\公众>
<beans:constructor-arg index=\"大众0\"大众 ref=\公众clientDetailsService\"大众 />
</beans:bean>
<!-- oauth2访问掌握,AffirmativeBased:有一个赞许就通过,ConsensusBased:票数多的通过,UnanimousBased:全部通过才能通过 -->
<beans:bean id=\"大众oauth2AccessDecisionManager\公众
class=\"大众org.springframework.security.access.vote.AffirmativeBased\"大众>
<beans:constructor-arg>
<beans:list>
<beans:bean class=\"大众org.springframework.security.oauth2.provider.vote.ScopeVoter\公众 />
<beans:bean class=\公众org.springframework.security.access.vote.RoleVoter\"大众>
<beans:property name=\"大众rolePrefix\"大众 value=\"大众\"大众 />
</beans:bean>
<beans:bean class=\公众org.springframework.security.access.vote.AuthenticatedVoter\"大众 />
</beans:list>
</beans:constructor-arg>
</beans:bean>
<!-- oauth2 server授权模式:目前系统利用authorization-code授权码模式获取token -->
<oauth2:authorization-server
client-details-service-ref=\"大众clientDetailsService\"大众 token-services-ref=\"大众tokenServices\"大众
user-approval-handler-ref=\"大众oauthUserApprovalHandler\"大众>
<oauth2:authorization-code authorization-code-services-ref=\公众jdbcAuthorizationCodeServices\公众 />
<oauth2:implicit />
<!-- 配置本做事器是否支持刷新token,默认支持刷新,不刷新就加上disabled=\"大众true\公众 -->
<oauth2:refresh-token />
<oauth2:client-credentials />
<oauth2:password />
</oauth2:authorization-server>
<!-- 授权码即authorization-code数据库操作类 -->
<beans:bean id=\公众jdbcAuthorizationCodeServices\"大众
class=\"大众org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices\"大众>
<beans:constructor-arg index=\公众0\"大众 ref=\"大众dataSourceSys\"大众 />
</beans:bean>
<!-- 用于把验证类型、用户名密码都作为表单参数提交的过滤器配置 -->
<beans:bean id=\"大众clientCredentialsTokenEndpointFilter\公众
class=\公众org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter\公众>
<beans:property name=\"大众authenticationManager\公众 ref=\公众oauth2AuthenticationManager\公众 />
</beans:bean>
<!-- 指定spring要保护的资源:如果没有这个,访问掌握的时候会说没有Authentication object -->
<oauth2:resource-server id=\公众restResourceServer\"大众
resource-id=\"大众rest-resource\"大众 token-services-ref=\"大众tokenServices\"大众 />
<!-- 访问掌握的配置:受保护的资源配置,以/rest/打头的要求都会被Oauth2.0监听到要求 -->
<http pattern=\"大众/rest/\公众 create-session=\"大众never\"大众
entry-point-ref=\公众oauth2AuthenticationEntryPoint\公众
access-decision-manager-ref=\"大众oauth2AccessDecisionManager\公众 use-expressions=\"大众false\公众>
<!-- 不做角色限定,默认利用已登录即可访问接口 -->
<intercept-url pattern=\"大众/rest/\"大众 access=\"大众IS_AUTHENTICATED_FULLY\"大众 />
<anonymous enabled=\公众false\"大众 />
<custom-filter ref=\公众restResourceServer\公众 before=\公众PRE_AUTH_FILTER\"大众 />
<access-denied-handler ref=\"大众oauth2AccessDeniedHandler\公众 />
<csrf disabled=\公众true\公众/>
</http>
<!-- Spring Security 验证配置,用于登录登出等操作 -->
<!-- IS_AUTHENTICATED_ANONYMOUSLY:许可匿名用户进入
IS_AUTHENTICATED_FULLY:许可登任命户进入
IS_AUTHENTICATED_REMEMBERED:许可登任命户和rememberMe用户进入
-->
<http disable-url-rewriting=\"大众false\"大众 use-expressions=\"大众true\"大众>
<intercept-url pattern=\公众/index.jsp\公众 access=\"大众permitAll\公众/>
<intercept-url pattern=\公众/sso/\"大众 access=\"大众permitAll\"大众/>
<form-login authentication-success-handler-ref=\"大众authSuccess\"大众 username-parameter=\"大众tms_username\"大众 password-parameter=\公众tms_password\公众
authentication-failure-url=\公众/login.jsp?login_error=1\公众
default-target-url=\"大众/index.jsp\"大众 login-page=\公众/login.jsp\"大众 login-processing-url=\"大众/tms_security_check\公众/>
<csrf disabled=\公众true\"大众/>
<logout logout-url=\"大众/logout\"大众 invalidate-session=\公众true\"大众 success-handler-ref=\"大众logoutSuccess\公众 />
<headers>
<frame-options policy=\"大众SAMEORIGIN\公众/>
</headers>
<session-management invalid-session-url=\"大众/login.jsp\"大众 />
</http>
<!-- 授权成功处理类 -->
<beans:bean id=\"大众authSuccess\公众 class=\公众com.spsoft.tms.security.security.AuthenticationSuccessHandlerImpl\公众 />
<!-- 登出成功处理类 -->
<beans:bean id=\"大众logoutSuccess\"大众 class=\公众com.spsoft.tms.security.security.CustomLogoutSuccessHandler\公众 />