今天就跟大家聊聊有关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的认证流程是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/wwh/blog/3094370