九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
OAuth2.0 最直觀配置

OAuth2.0基礎(chǔ)認(rèn)識(shí)可以看這里

spring 全家桶已經(jīng)實(shí)現(xiàn)了 OAuth2.0 的全部功能(spring-cloud-starter-security、spring-security-oauth2-autoconfigure),我們只要引用對(duì)應(yīng)庫(kù)就可以了。

表結(jié)構(gòu)

無(wú)論哪種認(rèn)證方式,總要把數(shù)據(jù)存儲(chǔ)起來(lái)(無(wú)論是在緩存還是 DB),OAuth2.0 依賴的數(shù)據(jù)一般是存放在 DB 中的,全部表結(jié)構(gòu)可以參考這里

其中不能省的表就這一個(gè):oauth_client_details(客戶端信息配置,當(dāng)然了表名可以自己隨便改)

 

 

其它用戶表、角色權(quán)限表、token 存儲(chǔ)表等等都可以用我們自己的業(yè)務(wù)表來(lái)做,token 可以存放在 redis 中。

數(shù)據(jù)結(jié)構(gòu)

用戶信息

org.springframework.security.core.userdetails.User

private String password;private final String username;privatefinal Set<GrantedAuthority> authorities;private final booleanaccountNonExpired;private final boolean accountNonLocked;private final booleancredentialsNonExpired;private final boolean enabled;

這個(gè)類可以自定義,繼承 User 就好了,一般都是用項(xiàng)目中的用戶類。

權(quán)限信息

可以是菜單權(quán)限,也可以數(shù)據(jù)權(quán)限,這個(gè)完全根據(jù)業(yè)務(wù)來(lái)自定義。

比如使用業(yè)務(wù)系統(tǒng)的角色 + 權(quán)限關(guān)系表,就可以知道當(dāng)前用戶能操作哪些菜單 / 數(shù)據(jù)(Set authorities)。

加密方式(針對(duì) password 模式)

認(rèn)證過(guò)程中提交的密碼不能是明文,如果不用默認(rèn)的加密方式,可以自定義(必須與數(shù)據(jù)庫(kù)中存儲(chǔ)密碼的加密方式匹配)。

@Beanpublic PasswordEncoder passwordEncoder(){    returnPasswordEncoderFactories.createDelegatingPasswordEncoder();}

自定義授權(quán)服務(wù)器配置

@Configuration@AllArgsConstructor@EnableAuthorizationServerpublicclass AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter{private final DataSource dataSource;private final UserDetailsServiceuserDetailsService;private final AuthenticationManagerauthenticationManager;    // 用戶信息和token存放在redis中privatefinal RedisConnectionFactoryredisConnectionFactory;@Override@SneakyThrowspublic voidconfigure(ClientDetailsServiceConfigurer clients){        // 自定義用戶查詢實(shí)現(xiàn)類MyClientDetailsService clientDetailsService = newMyClientDetailsService(dataSource);       // 自定義查詢oauth_client_details數(shù)據(jù)的sql(根據(jù)client_id查詢)clientDetailsService.setSelectClientDetailsSql("select* from ...");        // 自定義查詢所有oauth_client_details數(shù)據(jù)的sqlclientDetailsService.setFindClientDetailsSql("select* from...");clients.withClientDetails(clientDetailsService);}@Overridepublicvoid configure(AuthorizationServerSecurityConfigurer oauthServer){oauthServer             //讓 /oauth/token 支持 client_id 以及 client_secret 作登錄認(rèn)證.allowFormAuthenticationForClients()            // 允許可訪問(wèn) /oauth/check_token 對(duì)應(yīng)的api.checkTokenAccess("permitAll()");}@Overridepublicvoid configure(AuthorizationServerEndpointsConfigurer endpoints){endpoints            // oauth請(qǐng)求使用get或put方式.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST)            // token存儲(chǔ)方式.tokenStore(tokenStore())            // 自定義token中附加信息的內(nèi)容.tokenEnhancer(tokenEnhancer())            // 獲取用戶信息的實(shí)現(xiàn)類.userDetailsService(userDetailsService).authenticationManager(authenticationManager)            // 是否重復(fù)使用refreshToken直到過(guò)期.reuseRefreshTokens(false)            // 自定義授權(quán)確認(rèn)api.pathMapping("/oauth/confirm_access","/token/confirm_access")            // 自定義異常處理類.exceptionTranslator(newMyWebResponseExceptionTranslator());}@Beanpublic TokenStore tokenStore(){RedisTokenStore tokenStore = newRedisTokenStore(redisConnectionFactory);tokenStore.setPrefix("myOAuth2.0");returntokenStore;}@Beanpublic TokenEnhancer tokenEnhancer() {return (accessToken,authentication) -> {final Map<String, Object> additionalInfo = newHashMap<>();additionalInfo.put("addInfo", "額外信息");((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfo);return accessToken;};}}

授權(quán)服務(wù)器正確分配了 token 后,在后續(xù)的請(qǐng)求過(guò)程中,資源服務(wù)器怎么從 token 上獲取用戶信息呢?這就需要在資源服務(wù)器中配置了。

自定義資源服務(wù)器配置

public class MyResourceServerConfigurerAdapter extendsResourceServerConfigurerAdapter {    // 自定義異常處理類@AutowiredprotectedResourceAuthExceptionEntryPoint resourceAuthExceptionEntryPoint;   // 驗(yàn)證token是否有效,默認(rèn)即可,無(wú)需自定義@AutowiredprotectedRemoteTokenServices remoteTokenServices;    // 自定義拒絕授權(quán)處理器@Autowiredprivate AccessDeniedHandlermyAccessDeniedHandler;    // 允許匿名訪問(wèn)的資源,支持ant通配符@Autowiredprivate List<String>permitUrls;    // rest請(qǐng)求模板,默認(rèn)即可@AutowiredprivateRestTemplate restTemplate;@Override@SneakyThrowspublic voidconfigure(HttpSecurity httpSecurity){ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistryregistry = httpSecurity.authorizeRequests();        //可匿名訪問(wèn)資源permitUrls.forEach(url ->registry.antMatchers(url).permitAll());       // 所有頁(yè)面需要授權(quán)registry.anyRequest().authenticated().and().csrf().disable();}@Overridepublicvoid configure(ResourceServerSecurityConfigurer resources) {DefaultAccessTokenConverteraccessTokenConverter = newDefaultAccessTokenConverter();        // 關(guān)鍵位置,根據(jù)check_token返回的結(jié)果,轉(zhuǎn)換為資源服務(wù)器中可用的用戶信息UserAuthenticationConverteruserTokenConverter = newMyUserAuthenticationConverter();accessTokenConverter.setUserTokenConverter(userTokenConverter);remoteTokenServices.setRestTemplate(restTemplate);remoteTokenServices.setAccessTokenConverter(accessTokenConverter);resources.authenticationEntryPoint(resourceAuthExceptionEntryPoint).accessDeniedHandler(myAccessDeniedHandler).tokenServices(remoteTokenServices);}}

這里的UserAuthenticationConverter 會(huì)根據(jù) check_token 返回的內(nèi)容來(lái)生成一個(gè) org.springframework.security.core.userdetails.User 并把它放在org.springframework.security.authentication.UsernamePasswordAuthenticationToken中,這樣后面的處理邏輯都能從權(quán)限管理器中獲取到用戶信息了。

那 check_token 是怎么獲取的 token 信息呢?

之前我們不是配置了 token 在 redis 中存儲(chǔ)么?

@Beanpublic TokenStore tokenStore() {   RedisTokenStore tokenStore = newRedisTokenStore(redisConnectionFactory);   tokenStore.setPrefix("myOAuth2.0");    returntokenStore;}

在 RedisTokenStore 中你會(huì)看到是如何反序列化出來(lái)的

@Overridepublic OAuth2AuthenticationreadAuthenticationForRefreshToken(OAuth2RefreshToken token) {   return readAuthenticationForRefreshToken(token.getValue());}publicOAuth2Authentication readAuthenticationForRefreshToken(String token) {    RedisConnectionconn = getConnection();    try{        byte[] bytes =conn.get(serializeKey(REFRESH_AUTH +token));        OAuth2Authentication auth =deserializeAuthentication(bytes);       return auth;    } finally{        conn.close();    }}

redis 中存儲(chǔ)的內(nèi)容如下,其實(shí)就是一個(gè)序列化的 org.springframework.security.oauth2.provider.OAuth2Authentication 對(duì)象

到這里,Oauth2.0 的配置就很清楚了吧,后面我們?cè)侔颜麄€(gè)請(qǐng)求過(guò)程串起來(lái),就更直觀了!

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
使用Spring Cloud Security OAuth2搭建授權(quán)服務(wù)
Oauth2 JWT登出(黑名單方案)
決定放棄 JWT 了!
理解JWT的使用場(chǎng)景和優(yōu)劣
可能是第二好的 Spring OAuth 2.0 文章,艿艿端午在家寫了 3 天~
微服務(wù)架構(gòu)SpringCloud
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服