bean名称为springSecurityFilterChainFilterChainProxy对象的filterChains
中三个DefaultSecurityFilterChain
第一个DefaultSecurityFilterChain,匹配路径/oauth/token,/oauth/token_key,/oauth/check_token
filters大小为12。filters[4]= ClientCredentialsTokenEndpointFilter过滤器。filters[9]为
SessionManagementFilter过滤器。
ClientCredentialsTokenEndpointFilter过滤器
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain){
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
// this.requiresAuthenticationRequestMatcher=ClientCredentialsTokenEndpointFilter$
// ClientCredentialsRequestMatcher内部类,其实现RequestMatcher接口。单参构造方法
// ClientCredentialsRequestMatcher(String path) path="/oauth/token"
// 请求路径是否匹配/oauth/token?
// 调用 !this.requiresAuthenticationRequestMatcher.matches(request);
if (!this.requiresAuthentication(request, response)) {
// 不匹配,则跳过该过滤器
chain.doFilter(request, response);
} else {
// 匹配,则继续执行
if (this.logger.isDebugEnabled()) {
this.logger.debug("Request is to process authentication");
}
Authentication authResult;
try {
authResult = this.attemptAuthentication(request, response)->{
String clientId = request.getParameter("client_id");
String clientSecret = request.getParameter("client_secret");
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
// 在threadLocal中获取authentication对象不为null,且已认证,则返回
return authentication;
}
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(clientId, clientSecret);
// 调用ProviderManager对象DaoAuthenticationProvider.userDetailsService=
// ClientDetailsUserDetailsService进行认证
return this.getAuthenticationManager().authenticate(authRequest);
}
};
if (authResult == null) {
return;
}
// 实现SessionAuthenticationStrategy.onAuthentication()接口的类
// 1.CompositeSessionAuthenticationStrategy List<SessionAuthenticationStrategy> delegateStrategies
// 2.NullAuthenticatedSessionStrategy
// 3.ChangeSessionIdAuthenticationStrategy
// 4.SessionFixationProtectionStrategy
this.sessionStrategy.onAuthentication(authResult, request, response);
} catch (InternalAuthenticationServiceException var8) {
this.logger.error("An internal error occurred while trying to authenticate the user.", var8);
this.unsuccessfulAuthentication(request, response, var8);
return;
} catch (AuthenticationException var9) {
this.unsuccessfulAuthentication(request, response, var9);
return;
}
if (this.continueChainBeforeSuccessfulAuthentication) {
chain.doFilter(request, response);
}
this.successfulAuthentication(request, response, chain, authResult);
}
}
SessionManagementFilter过滤器
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
if (request.getAttribute("__spring_security_session_mgmt_filter_applied") != null) {
chain.doFilter(request, response);
} else {
request.setAttribute("__spring_security_session_mgmt_filter_applied", Boolean.TRUE);
if (!this.securityContextRepository.containsContext(request)) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && !this.trustResolver.isAnonymous(authentication)) {
try {
// sessionAuthenticationStrategy=CompositeSessionAuthenticationStrategy
// 其类List<SessionAuthenticationStrategy> delegateStrategies;
// delegateStrategies[0]=ChangeSessionIdAuthenticationStrategy
//
this.sessionAuthenticationStrategy.onAuthentication(authentication, request, response);
} catch (SessionAuthenticationException var8) {
this.logger.debug("SessionAuthenticationStrategy rejected the authentication object", var8);
SecurityContextHolder.clearContext();
this.failureHandler.onAuthenticationFailure(request, response, var8);
return;
}
this.securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response);
} else if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Requested session ID " + request.getRequestedSessionId() + " is invalid.");
}
if (this.invalidSessionStrategy != null) {
this.invalidSessionStrategy.onInvalidSessionDetected(request, response);
return;
}
}
}
chain.doFilter(request, response);
}
OAuth2AuthenticationProcessingFilter过滤器
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
// TokenExtractor接口Authentication extract(HttpServletRequest var1)
// 实现类BearerTokenExtractor
// Authentication extract(HttpServletRequest request){
//
// String tokenValue = this.extractToken(request);
// }
Authentication authentication = this.tokenExtractor.extract(request);
}
SessionRepositoryFilter过滤器
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain){
// 向请求中放入org.springframework.session.SessionRepository=this.sessionRepository
// org.springframework.session接口SessionRepository<S extends Session>
// S createSession();void save(S var1);S findById(String var1);
// void deleteById(String var1);
// RedisIndexedSessionRepository类
request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
}
TokenEndpoint对象
@RequestMapping(
value = {"/oauth/token"},
method = {RequestMethod.POST}
)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters){
String clientId = this.getClientId(principal);
// 认证
ClientDetails authenticatedClient = this.getClientDetailsService().loadClientByClientId(clientId);
// OAuth2RequestFactory接口方法createAuthorizationRequest(),createOAuth2Request
// createTokenRequest()
// 实现类DefaultOAuth2RequestFactory
TokenRequest tokenRequest = this.getOAuth2RequestFactory().createTokenRequest(parameters, authenticatedClient)->{
String clientId = (String)requestParameters.get("client_id");
if (clientId == null) {
clientId = authenticatedClient.getClientId();
} else if (!clientId.equals(authenticatedClient.getClientId())) {
throw new InvalidClientException("Given client ID does not match authenticated client");
}
String grantType = (String)requestParameters.get("grant_type");
// OAuth2Utils解析参数中的scopes,如果为null,根据clientId获取用户scopes返回
Set<String> scopes = this.extractScopes(requestParameters, clientId);
// BaseRequest抽象类属性clientId,scope,requestParameters
// TokenRequest继承BaseRequest类,属性grantType
// OAuth2Request继承BaseRequest类,属性resourceIds,authorities,approved
// refresh刷新令牌,redirectUri,responseTypes,extensions请求附加信息
//
TokenRequest tokenRequest = new TokenRequest(requestParameters, clientId, scopes, grantType);
if (authenticatedClient != null) {
// DefaultOAuth2RequestValidator类验证请求中scope与用户详情中的scope
// 如果请求中的scope,不包含在用户详情的scope中,则抛出异常
oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
}
// tokenRequest对象的grantType不能为null
// 如果tokenRequest对象的grantType等于"authorization_code"且code不为null。则tokenRequest的
// 的scope不为null,则设置scope为null。
// 如果tokenRequest对象的grantType等于"refresh_token"且refresh_token不为null。则tokenRequest的
// 的scope设置为请求中的scope。
// TokenGranter接口OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest);
// AbstractTokenGranter类,属性
// AuthorizationServerTokenServices tokenServices=DefaultTokenServices;accessTokenValiditySeconds=12hours,refreshTokenValiditySeconds=30day
// ClientDetailsService clientDetailsService;OAuth2RequestFactory requestFactory;String grantType;
// 2.RefreshTokenGranter继承AbstractTokenGranter,属性String GRANT_TYPE = "refresh_token";
// 1.AuthorizationCodeTokenGranter继承AbstractTokenGranter,其属性String GRANT_TYPE = "authorization_code";AuthorizationCodeServices authorizationCodeServices;
// 4.ClientCredentialsTokenGranter继承AbstractTokenGranter,其属性String GRANT_TYPE = "client_credentials";boolean allowRefresh = false;
// 5.ResourceOwnerPasswordTokenGranter继承AbstractTokenGranter,其属性String GRANT_TYPE = "password";AuthenticationManager authenticationManager;
// 3.ImplicitTokenGranter继承AbstractTokenGranter,其属性String GRANT_TYPE = "implicit";
// CompositeTokenGranter继承AbstractTokenGranter,其属性List<TokenGranter> tokenGranters;
// OAuth2AccessToken接口,属性BEARER_TYPE = "Bearer",OAUTH2_TYPE = "OAuth2",ACCESS_TOKEN = "access_token",TOKEN_TYPE = "token_type",
// EXPIRES_IN = "expires_in";REFRESH_TOKEN = "refresh_token",SCOPE = "scope";
// DefaultOAuth2AccessToken实现接口OAuth2AccessToken
// 属性String value;Date expiration;String tokenType ="bearer";Set<String> scope;
// Map<String, Object> additionalInformation;OAuth2RefreshToken refreshToken;
// OAuth2RefreshToken接口String getValue()
// DefaultOAuth2RefreshToken类实现OAuth2RefreshToken,属性String value;
// DefaultExpiringOAuth2RefreshToken类继承OAuth2RefreshToken,ExpiringOAuth2RefreshToken。其属性Date expiration;
// OAuth2AccessToken grant = granter.grant(grantType, tokenRequest);
// ResourceOwnerPasswordTokenGranter.grant(grantType, tokenRequest)->{
// String clientId = tokenRequest.getClientId();
// ClientDetails client = clientDetailsService.loadClientByClientId(clientId);
// validateGrantType(grantType, client);
// //创建OAuth2Request对象,创建OAuth2Authentication对象
// return getAccessToken(client, tokenRequest);
// };
OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest)->{
OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication)->{
// tokenServices = DefaultTokenServices,其中tokenStore = RedisTokenStore类
return tokenServices.createAccessToken(getOAuth2Authentication(client, tokenRequest))->{
// 利用userName,client_id,scope生成key。 String key = authenticationKeyGenerator.extractKey(authentication);
// 序列化 auth_to_access:key
// 通过 auth_to_access:key从redis得到OAuth2AccessToken对象
// 如果accessToken为null,则返回OAuth2AccessToken。不为null,更新可能改变的details
OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication);
OAuth2RefreshToken refreshToken = null;
// 从redis取出OAuth2AccessToken对象不为null
if (existingAccessToken != null) {
}
// OAuth2AccessToken对象为null时。refreshToken为null时,创建刷新token
if (refreshToken == null) {
// 取ClientDetail对象的grantType是否包含refresh_token,
// 从ClientDetail对象取出validitySeconds,大于0,则DefaultExpiringOAuth2RefreshToken,否则DefaultOAuth2RefreshToken
refreshToken = createRefreshToken(authentication);
// 如果 refreshToken不为null,且为ExpiringOAuth2RefreshToken。且已过期,则重新生成刷新令牌
}else if (refreshToken instanceof ExpiringOAuth2RefreshToken){}
// 创建OAuth2AccessToken对象
// 使用UUID创建DefaultOAuth2AccessToken对象,设置过时间,设置刷新token,设置scope。
// accessTokenEnhancer不为null时,调用enhance()方法
// serializedAccessToken为OAuth2AccessToken对象,serializedAuth为OAuth2Authentication对象
// accessKey为access:OAuth2AccessToken.getValue()
// authKey为auth:OAuth2AccessToken.getValue()
// authToAccessKey为auth_to_access:md5(username+client_id+scope)
// approvalKey为uname_to_access:clientId+username
// clientId为client_id_to_access:clientId
// accessKey=serializedAccessToken,authKey=serializedAuth,authToAccessKey=serializedAccessToken
// approvalKey=serializedAccessToken,clientId=serializedAccessToken
// accessToRefreshKey=access_to_refresh:token.getValue()==token.getRefreshToken().getValue()
// refreshToAccessKey=refresh_to_access:token.getRefreshToken().getValue()==token.getValue()
OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken); }
};
};
};
return tokenRequest;
};
}
BaseClientDetails类属性
clientId,clientSecret,scope,resourceIds,authorizedGrantTypes,registeredRedirectUris,
autoApproveScopes,authorities,accessTokenValiditySeconds,refreshTokenValiditySeconds,
additionalInformation额外信息。
AuthorizationServerEndpointsConfigurer类
// AuthorizationServerTokenServices接口createAccessToken(),refreshAccessToken
// DefaultTokenServices实现接口AuthorizationServerTokenServices
private AuthorizationServerTokenServices tokenServices;
// ConsumerTokenServices接口revokeToken(String tokenValue)
// DefaultTokenServices实现接口ConsumerTokenServices
private ConsumerTokenServices consumerTokenServices;
// AuthorizationCodeServices接口String createAuthorizationCode(OAuth2Authentication authentication);OAuth2Authentication consumeAuthorizationCode(String code)
// RandomValueAuthorizationCodeServices抽象类实现接口AuthorizationCodeServices,其属性RandomValueStringGenerator generator = new RandomValueStringGenerator();
// 抽象方法store(String code, OAuth2Authentication authentication);
// 抽象方法OAuth2Authentication remove(String code);
// InMemoryAuthorizationCodeServices类继承RandomValueAuthorizationCodeServices抽象类
// 属性 ConcurrentHashMap<String, OAuth2Authentication> authorizationCodeStore = new ConcurrentHashMap<String, OAuth2Authentication>()
// JdbcAuthorizationCodeServices类继承RandomValueAuthorizationCodeServices抽象类
// 属性String DEFAULT_SELECT_STATEMENT = "select code, authentication from oauth_code where code = ?";
// String DEFAULT_INSERT_STATEMENT = "insert into oauth_code (code, authentication) values (?, ?)";
// String DEFAULT_DELETE_STATEMENT = "delete from oauth_code where code = ?";
private AuthorizationCodeServices authorizationCodeServices;
// ResourceServerTokenServices接口loadAuthentication(String accessToken),readAccessToken(String accessToken);
// DefaultTokenServices实现ResourceServerTokenServices接口
private ResourceServerTokenServices resourceTokenServices;
// TokenStore接口OAuth2Authentication readAuthentication(OAuth2AccessToken token);storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication);
// JdbcTokenStore继承接口TokenStore
// RedisTokenStore继承接口TokenStore
// JwtTokenStore继承接口TokenStore
// InMemoryTokenStore继承接口TokenStore
// JdbcTokenStore继承接口TokenStore
private TokenStore tokenStore;
// 提供自定义令牌的机会TokenEnhancer接口OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication);
// TokenEnhancerChain实现TokenEnhancer接口,属性private List<TokenEnhancer> delegates = Collections.emptyList();
// AccessTokenConverter接口convertAccessToken(),extractAccessToken,extractAuthentication
// 属性String AUD = "aud";String CLIENT_ID = "client_id";String EXP = "exp"; String JTI = "jti";String GRANT_TYPE = "grant_type";
// String ATI = "ati";String SCOPE = OAuth2AccessToken.SCOPE;String AUTHORITIES = "authorities";
// DefaultAccessTokenConverter类实现AccessTokenConverter接口
// 属性UserAuthenticationConverter userTokenConverter,boolean includeGrantType;String scopeAttribute = SCOPE;String clientIdAttribute = CLIENT_ID;
// JwtAccessTokenConverter类,其属性AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
// OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication)->{
// DefaultOAuth2AccessToken result = new DefaultOAuth2AccessToken(accessToken);
// Map<String, Object> info = new LinkedHashMap<String, Object>(accessToken.getAdditionalInformation());
// info.put("jti",tokenId);
// result.setAdditionalInformation(info);
// // Signer signer = new MacSigner(verifierKey)
// // content =objectMapper.formatMap(DefaultAccessTokenConverter.convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication)
// // ),
// // content={"aud":["rereere"],"user_name":"user","jti":"aeb1a04f-1784-4499-b4dc-ea3ec70ccd57","client_id":"clientId","authorities:""}
// // JwtHelper.encode(content, signer).getEncoded()
// result.setValue(encode(result, authentication));
// }
private TokenEnhancer tokenEnhancer;
// 5中认证
private TokenGranter tokenGranter;
// ApprovalStore接口addApprovals(),revokeApprovals(Collection<Approval> approvals);
// Approval类String userId;String clientId;String scope;Date expiresAt;Date lastUpdatedAt;ApprovalStatus status;
// TokenApprovalStore实现ApprovalStore接口。// InMemoryApprovalStore实现ApprovalStore接口
private ApprovalStore approvalStore;