日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Security OAuth2源码解析(二)

發布時間:2024/4/13 javascript 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Security OAuth2源码解析(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鑒權服務器對客戶端鑒權之后,會生成token,客戶端使用token,就可以去資源服務器獲取資源。

@EnableResourceServer?

@Import(ResourceServerConfiguration.class) public @interface EnableResourceServer {}

ResourceServerConfiguration

ResourceServerConfigurationWebSecurityConfigurerAdapter的子類實現。引入了ResourceServerSecurityConfigurerResourceServerTokenServices

@Overrideprotected void configure(HttpSecurity http) throws Exception {//引入Filter配置ResourceServerSecurityConfigurer resources = new ResourceServerSecurityConfigurer();//引入ResourceServerTokenServicesResourceServerTokenServices services = resolveTokenServices();if (services != null) {resources.tokenServices(services);}else {if (tokenStore != null) {resources.tokenStore(tokenStore);}else if (endpoints != null) {resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore());}}if (eventPublisher != null) {resources.eventPublisher(eventPublisher);}for (ResourceServerConfigurer configurer : configurers) {configurer.configure(resources);}//匿名驗證,http.authenticationProvider(new AnonymousAuthenticationProvider("default"))// 異常處理.exceptionHandling().accessDeniedHandler(resources.getAccessDeniedHandler()).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable();//filter chainhttp.apply(resources);if (endpoints != null) {// Assume we are in an Authorization Serverhttp.requestMatcher(new NotOAuthRequestMatcher(endpoints.oauth2EndpointHandlerMapping()));}for (ResourceServerConfigurer configurer : configurers) {// Delegates can add authorizeRequests() hereconfigurer.configure(http);}if (configurers.isEmpty()) {//所有請求需授權http.authorizeRequests().anyRequest().authenticated();}}

ResourceServerSecurityConfigurer

ResourceServerSecurityConfigurer配置了:OAuth2AuthenticationProcessingFilter

@Overridepublic void configure(HttpSecurity http) throws Exception {//如果是OAuth2AuthenticationManager,則設置tokenService等。AuthenticationManager oauthAuthenticationManager = oauthAuthenticationManager(http);resourcesServerFilter = new OAuth2AuthenticationProcessingFilter();resourcesServerFilter.setAuthenticationEntryPoint(authenticationEntryPoint);resourcesServerFilter.setAuthenticationManager(oauthAuthenticationManager);if (eventPublisher != null) {resourcesServerFilter.setAuthenticationEventPublisher(eventPublisher);}if (tokenExtractor != null) {resourcesServerFilter.setTokenExtractor(tokenExtractor);}if (authenticationDetailsSource != null) {resourcesServerFilter.setAuthenticationDetailsSource(authenticationDetailsSource);}resourcesServerFilter = postProcess(resourcesServerFilter);resourcesServerFilter.setStateless(stateless);// @formatter:offhttp.authorizeRequests().expressionHandler(expressionHandler).and()//把OAuth2AuthenticationProcessingFilter 放在 AbstractPreAuthenticatedProcessingFilter 之前。.addFilterBefore(resourcesServerFilter, AbstractPreAuthenticatedProcessingFilter.class).exceptionHandling().accessDeniedHandler(accessDeniedHandler).authenticationEntryPoint(authenticationEntryPoint);// @formatter:on}

?OAuth2AuthenticationManager?

private AuthenticationManager oauthAuthenticationManager(HttpSecurity http) {OAuth2AuthenticationManager oauthAuthenticationManager = new OAuth2AuthenticationManager();if (authenticationManager != null) {if (authenticationManager instanceof OAuth2AuthenticationManager) {oauthAuthenticationManager = (OAuth2AuthenticationManager) authenticationManager;}else {return authenticationManager;}}oauthAuthenticationManager.setResourceId(resourceId);oauthAuthenticationManager.setTokenServices(resourceTokenServices(http));oauthAuthenticationManager.setClientDetailsService(clientDetails());return oauthAuthenticationManager;}

OAuth2AuthenticationProcessingFilter?

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 {//提取AuthenticationAuthentication 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 {//設置ACCESS_TOKEN_VALUE到request,request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, authentication.getPrincipal());if (authentication instanceof AbstractAuthenticationToken) {AbstractAuthenticationToken needsDetails = (AbstractAuthenticationToken) authentication;needsDetails.setDetails(authenticationDetailsSource.buildDetails(request));}//驗證, authenticationManager 是 OAuth2AuthenticationManagerAuthentication authResult = authenticationManager.authenticate(authentication);if (debug) {logger.debug("Authentication success: " + authResult);}eventPublisher.publishAuthenticationSuccess(authResult);SecurityContextHolder.getContext().setAuthentication(authResult);}}catch (OAuth2Exception failed) {SecurityContextHolder.clearContext(); ........return;}chain.doFilter(request, response);}

?TokenExtractor?

從請求中提取Authentication?

public interface TokenExtractor {Authentication extract(HttpServletRequest request);}

?BearerTokenExtractor

TokenExtractor 的默認實現,Bearer方式,從header中提取。

protected String extractHeaderToken(HttpServletRequest request) {Enumeration<String> headers = request.getHeaders("Authorization");while (headers.hasMoreElements()) { // typically there is only one (most servers enforce that)String value = headers.nextElement(); //Bearerif ((value.toLowerCase().startsWith(OAuth2AccessToken.BEARER_TYPE.toLowerCase()))) {String authHeaderValue = value.substring(OAuth2AccessToken.BEARER_TYPE.length()).trim();// Add this here for the auth details later. Would be better to change the signature of this method.request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE,value.substring(0, OAuth2AccessToken.BEARER_TYPE.length()).trim());int commaIndex = authHeaderValue.indexOf(',');if (commaIndex > 0) {authHeaderValue = authHeaderValue.substring(0, commaIndex);}return authHeaderValue;}}return null;}

OAuth2AuthenticationManager?

public Authentication authenticate(Authentication authentication) throws AuthenticationException {if (authentication == null) {throw new InvalidTokenException("Invalid token (token not found)");}//獲取token,默認是一個UUID,String token = (String) authentication.getPrincipal();//根據token獲取AuthenticationOAuth2Authentication auth = tokenServices.loadAuthentication(token);if (auth == null) {throw new InvalidTokenException("Invalid token: " + token);}//資源列表Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds();if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) {throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")");}//檢測客戶端信息checkClientDetails(auth);if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) {OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();// Guard against a cached copy of the same detailsif (!details.equals(auth.getDetails())) {// Preserve the authentication details from the one loaded by token servicesdetails.setDecodedDetails(auth.getDetails());}}auth.setDetails(authentication.getDetails());auth.setAuthenticated(true);return auth;}

ResourceServerTokenServices

ResourceServerTokenServices實現加載Authentication和讀取token的功能。

public interface ResourceServerTokenServices {OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException;OAuth2AccessToken readAccessToken(String accessToken); }

?流程:

圖從其他地方copy的。

總結

以上是生活随笔為你收集整理的Spring Security OAuth2源码解析(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。