认证鉴权服务基于Spring Security 、Spring cloud Oauth2实现整个框架安全认证,提供统一权限认证受权及资源访问服务解决方案,认证中心默认提供密码模式(password),并支持原生 token 交互访问业务。前端
OAuth2用户是一个标准化的受权协议/框架,OAuth 2.0受权框架使第三方应用程序来获取对HTTP服务的有限访问机会。不管是经过编排资源全部者和HTTP服务之间的交互批准的资源全部者,或经过容许第三方应用程序来获取本身的访问权限。redis
(A)用户打开客户端之后,客户端要求用户给予受权。数据库
(B)用户赞成给予客户端受权。json
(C)客户端使用上一步得到的受权,向认证服务器申请令牌。缓存
(D)认证服务器对客户端进行认证之后,确认无误,赞成发放令牌。安全
(E)客户端使用令牌,向资源服务器申请获取资源。服务器
(F)资源服务器确认令牌无误,赞成向客户端开放资源。app
OAuth2.0认证步骤:框架
(A)用户向客户端提供用户名和密码。分布式
(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。
(C)认证服务器确认无误后,向客户端提供访问令牌。
客户端请求发出的HTTP方式:
POST /token HTTP/1.1
Host: /auth/oauth/token
Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=104573622026289&password=admin123
认证服务器返回认证消息:
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"
}
├── ui -- 前端工程 ├── framework-auth -- 认证、鉴权服务模块
├── framework-common -- 公用模块 ├ └── framework-common-cores -- 公共工具类核心包 ├ └── framework-common-security -- 安全工具类 ├ ├── framework-oauth -- 认证鉴权服务
├ ├──framework-system -- 组织机构权限服务
描述:咱们须要向这个类中, 配置用户信息, 生成对应的AuthenticationManager, 同时做为用户身份的管理者,提供认证入口。
AuthorizationServerConfigurerAdapter介绍:
WebSecurityConfigurerAdapter介绍:
配置Security的认证策略,authorizeRequests()配置路径拦截,代表路径访问所对应的权限,角色,认证信息。像WebSecurityConfigurerAdapter中配置用户信息, 生成对应的AuthenticationManager做为用户身份的管理者;UserDetailsService用于获取用户的信息,本案例从数据库获取存到分布式缓存中。
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers( "/token/**").permitAll()
.anyRequest().authenticated()
.and().csrf().disable();
}
2.OAuth2.0 暴露获取令牌TokenEndpoint
/oauth/token:令牌端点
TokenEndpoint:用来做为请求者得到令牌(Token)的服务,默认的路径 /oauth/token,
定义受权和令牌端点以及令牌服务
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancer())
.userDetailsService(userDetailsService)
.authenticationManager(authenticationManager)
.reuseRefreshTokens(false)
.exceptionTranslator(new CustomWebResponseExceptionTranslator());
}
3.认证中心服务容器监听认证结果
ApplicationListener<AuthenticationSuccessEvent>、ApplicationListener<AbstractAuthenticationFailureEvent>
MerAuthenticationSuccessEventHandler 继承 AuthenticationSuccessEvent处理成功返回认证、鉴权的结果。
public void handle(Authentication authentication) {
ClientDetails clientDetails = clientDetailsService.loadClientByClientId(StringConstnts.CLIENT_ID);
TokenRequest tokenRequest = new TokenRequest(new HashMap<>(), StringConstnts.CLIENT_ID, clientDetails.getScope(), "password");
OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
OAuth2Authentication auth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
OAuth2AccessToken token = tokenStore.getAccessToken(auth2Authentication);
OAuth2AccessToken token1 = authorizationServerTokenServices.getAccessToken(auth2Authentication);
redisTemplate.opsForValue().set(token, authentication.getAuthorities());
log.info("用户:{} 登陆成功", authentication.getPrincipal());
}
MerAuthenticationFailureEvenHandler 继承 AbstractAuthenticationFailureEvent 认证失败返回失败消息体。
public void onApplicationEvent(AbstractAuthenticationFailureEvent event) { AuthenticationException authenticationException = event.getException(); Authentication authentication = (Authentication) event.getSource(); handle(authenticationException, authentication); }