今天就跟大家聊聊有关Spring security oauth2的认证流程是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
@Override public void configure(HttpSecurity http) throws Exception { AuthenticationManager oauthAuthenticationManager = oauthAuthenticationManager(http); resourcesServerFilter = new OAuth3AuthenticationProcessingFilter(); resourcesServerFilter.setAuthenticationEntryPoint(authenticationEntryPoint); resourcesServerFilter.setAuthenticationManager(oauthAuthenticationManager); if (eventPublisher != null) { resourcesServerFilter.setAuthenticationEventPublisher(eventPublisher); } if (tokenExtractor != null) { //添加token的额外解析方法 默认调用BearerTokenExtractor resourcesServerFilter.setTokenExtractor(tokenExtractor); } if (authenticationDetailsSource != null) { resourcesServerFilter.setAuthenticationDetailsSource(authenticationDetailsSource); } resourcesServerFilter = postProcess(resourcesServerFilter); resourcesServerFilter.setStateless(stateless); // @formatter:off http .authorizeRequests().expressionHandler(expressionHandler) .and() .addFilterBefore(resourcesServerFilter, AbstractPreAuthenticatedProcessingFilter.class) .exceptionHandling() .accessDeniedHandler(accessDeniedHandler) .authenticationEntryPoint(authenticationEntryPoint); // @formatter:on }
OAuth3AuthenticationProcessingFilter中作为filter拦截认证会借助tokenExtractor从request中获取token的值,将其转换为Authentication 对象。
public class OAuth3AuthenticationProcessingFilter implements Filter, InitializingBean { ... public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { final boolean debug = logger.isDebugEnabled(); final HttpServletRequest request = (HttpServletRequest) req; final HttpServletResponse response = (HttpServletResponse) res; try { //调用TokenExtractor从httpRequest解析出对应的token值,将其转化为Authentication对象。 Authentication authentication = tokenExtractor.extract(request); if (authentication == null) { if (stateless && isAuthenticated()) { if (debug) { logger.debug("Clearing security context."); } SecurityContextHolder.clearContext(); } if (debug) { logger.debug("No token in request, will continue chain."); } } else { request.setAttribute(OAuth3AuthenticationDetails.ACCESS_TOKEN_VALUE, authentication.getPrincipal()); if (authentication instanceof AbstractAuthenticationToken) { AbstractAuthenticationToken needsDetails = (AbstractAuthenticationToken) authentication; needsDetails.setDetails(authenticationDetailsSource.buildDetails(request)); } //2调用的Authenticationd对象,调用authenticationManager.authenticate的方法 来判断用户是否登陆成功 Authentication authResult = authenticationManager.authenticate(authentication); if (debug) { logger.debug("Authentication success: " + authResult); } eventPublisher.publishAuthenticationSuccess(authResult); SecurityContextHolder.getContext().setAuthentication(authResult); } } catch (OAuth3Exception failed) { SecurityContextHolder.clearContext(); if (debug) { logger.debug("Authentication request failed: " + failed); } eventPublisher.publishAuthenticationFailure(new BadCredentialsException(failed.getMessage(), failed), new PreAuthenticatedAuthenticationToken("access-token", "N/A")); authenticationEntryPoint.commence(request, response, new InsufficientAuthenticationException(failed.getMessage(), failed)); return; } chain.doFilter(request, response); } } .... }
认证执行结束之后,继续走configure中的配置的权限认证过滤操作 AuthenticationManager 默认实现方式是配置的OAuth3AuthenticationManager,所以OAuth3AuthenticationManager中的
--ResourceServerSecurityConfigurer.java private AuthenticationManager oauthAuthenticationManager(HttpSecurity http) { OAuth3AuthenticationManager oauthAuthenticationManager = new OAuth3AuthenticationManager(); if (authenticationManager != null) { if (authenticationManager instanceof OAuth3AuthenticationManager) { oauthAuthenticationManager = (OAuth3AuthenticationManager) authenticationManager; } else { return authenticationManager; } } oauthAuthenticationManager.setResourceId(resourceId); //配置tokenService解析方式 oauthAuthenticationManager.setTokenServices(resourceTokenServices(http)); oauthAuthenticationManager.setClientDetailsService(clientDetails()); return oauthAuthenticationManager; } private ResourceServerTokenServices resourceTokenServices(HttpSecurity http) { tokenServices(http); return this.resourceTokenServices; } private ResourceServerTokenServices tokenServices(HttpSecurity http) { if (resourceTokenServices != null) { return resourceTokenServices; } DefaultTokenServices tokenServices = new DefaultTokenServices(); //指定token的解析方式 tokenServices.setTokenStore(tokenStore()); tokenServices.setSupportRefreshToken(true); tokenServices.setClientDetailsService(clientDetails()); this.resourceTokenServices = tokenServices; return tokenServices; }
种模式
InMemoryTokenStore
JdbcTokenStore
JwtTokenStore
JwkTokenStore
RedisTokenStore
--OAuth3AuthenticationManager认证管理 public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (authentication == null) { throw new InvalidTokenException("Invalid token (token not found)"); } String token = (String) authentication.getPrincipal(); //从指定的实现的tokenStore中获取对应的值 OAuth3Authentication auth = tokenServices.loadAuthentication(token); if (auth == null) { throw new InvalidTokenException("Invalid token: " + token); } Collection<String> resourceIds = auth.getOAuth3Request().getResourceIds(); if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) { throw new OAuth3AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")"); } checkClientDetails(auth); if (authentication.getDetails() instanceof OAuth3AuthenticationDetails) { OAuth3AuthenticationDetails details = (OAuth3AuthenticationDetails) authentication.getDetails(); // Guard against a cached copy of the same details if (!details.equals(auth.getDetails())) { // Preserve the authentication details from the one loaded by token services details.setDecodedDetails(auth.getDetails()); } } auth.setDetails(authentication.getDetails()); auth.setAuthenticated(true); return auth; }
看完上述内容,你们对Spring security oauth2的认证流程是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。