亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringSecurityOAuth2 如何自定義token信息

 更新時間:2021年06月23日 10:18:04   作者:無小農(nóng)  
這篇文章主要介紹了SpringSecurityOAuth2 自定義token信息的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

GitHub地址

碼云地址

OAuth2默認的token返回最多只攜帶了5個參數(shù)(client_credentials模式只有4個 沒有refresh_token)

下面是一個返回示例:

{
    "access_token": "1e93bc23-32c8-428f-a126-8206265e17b2",
    "token_type": "bearer",
    "refresh_token": "0f083e06-be1b-411f-98b0-72be8f1da8af",
    "expires_in": 3599,
    "scope": "auth api"
}

然后我們需要的token可能需要增加username等自定義參數(shù):

{
    "access_token": "1e93bc23-32c8-428f-a126-8206265e17b2",
    "token_type": "bearer",
    "refresh_token": "0f083e06-be1b-411f-98b0-72be8f1da8af",
    "expires_in": 3599,
    "scope": "auth api",
    "username":"username"
}

具體實現(xiàn)自定義token步驟如下: 新建一個自定義token信息的新建自定義token返回MyTokenEnhancer實現(xiàn)TokenEnhancer接口重寫enhance方法:

/**
 * @Description 自定義token返回值
 * @Author wwz
 * @Date 2019/07/31
 * @Param
 * @Return
 */
public class MyTokenEnhancer implements TokenEnhancer {
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        User user = (User) authentication.getPrincipal();
        final Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put("username", user.getUsername());
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
        return accessToken;
    }
}

然后在認證服務(wù)配置AuthorizationServerEndpointsConfigurer中加上 MyTokenEnhancer。

這里劃重點 因為我這里指定了了defaultTokenServices()所以得在這個方法里加上配置

還有,如果已經(jīng)生成了一次沒有自定義的token信息,需要去redis里刪除掉該token才能再次測試結(jié)果,不然你的結(jié)果一直是錯誤的,因為token還沒過期的話,是不會重新生成的。

Spring Security 使用JWT自定義Token

敘述

默認的token生成規(guī)則其實就是一個UUID,就是一個隨機的字符串,然后存到redis中去,使用JWT的話,token中可以存放一些信息,我們服務(wù)端也不需要保存這個token, 服務(wù)器通過使用保存的密鑰驗證token的正確性,只要正確即通過驗證

使用JWT,在分布式系統(tǒng)中,很好地解決了單點登錄問題,很容易解決了session共享的問題.但是是無法作廢已頒布的令牌/不易應(yīng)對數(shù)據(jù)過期,因為 token 并沒有保存到服務(wù)端, 下面來看一下如何去配置JWT

配置JWT

TokenStoreConfig 這個類中要做一些修改,之前我們只在這個類里面配置了 redis 的存儲,現(xiàn)在把 JWT 的配置也加上,如下:

@Configuration
public class TokenStoreConfig { 
    @Autowired
    private RedisConnectionFactory connectionFactory;
 
    @Bean
    @ConditionalOnProperty(prefix = "core.security.oAuth2", name="tokenStore", havingValue="redis")
    public TokenStore redisTokenStore(){
        return new RedisTokenStore(connectionFactory);
    } 
    @Configuration
    @ConditionalOnProperty(prefix = "core.security.oAuth2", name="tokenStore", havingValue="jwt", matchIfMissing = true)
    public static class JwtTokenConfig{
 
        @Autowired
        private SecurityProperties securityProperties;
 
        @Bean
        public TokenStore jwtTokenStore(){
            return new JwtTokenStore(jwtAccessTokenConverter());
        }
 
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter(){
            // token生成中的一些處理
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setSigningKey(securityProperties.getOAuth2().getJwtTokenSignKey());
            return converter;
        } 
    }
}

這里首先是一個內(nèi)部的靜態(tài)類 JwtTokenConfig 用來配置 JWT 的一些配置,第一個方法 jwtTokenStore() 就是配置token的存儲,然后這里需要一個 JwtAccessTokenConverter 因為 TokenStore 只管 Token 的存儲,生成規(guī)則還需要配置,所以 jwtAccessTokenConverter() 就是用來做一些 Token 的處理

這個類上有一個注解

@ConditionalOnProperty(prefix = "core.security.oAuth2", name="tokenStore", havingValue="jwt", matchIfMissing = true)

意思就是,在配置中有 core.security.oAuth2.tokenStore 這個配置,而且值是 jwt 的話,就生效,最后有一個 matchIfMissing = true ,這個表示, 如果配置中沒有這個配置的話,也生效

上面的 redisTokenStore 也加了這個注解,但是沒有 matchIfMissing 默認是 false, 總的配置就是如果在配置中沒有指定哪種 tokenStore 的話,就默認的用 jwt ,如果想要使用 redis 存儲的話,必須明確的指定 core.security.oAuth2.tokenStore: redis

最后認證服務(wù)的配置中還需要做一些修改

@Configuration
@EnableAuthorizationServer
public class MyAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { 
    @Autowired(required = false)
    private JwtAccessTokenConverter jwtAccessTokenConverter; 
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        
        // ... 省略其他配置
 
        // 只有配置使用JWT的時候才會生效
        if (jwtAccessTokenConverter != null) {
            endpoints.accessTokenConverter(jwtAccessTokenConverter);
        }
     }
 
    // ... 省略其他代碼
}

這里,就是給 endpoints 指定一下 JwtAccessTokenConverter 就可以了

測試

請求 Token 還是跟之前的方式一樣的, 如下:

可以看到這里的token就是使用jwt了

在 jwt.io 中可以把剛剛生成的token解析一下,內(nèi)容如下:

這個就是我們生成的 JWT 中包含的信息

TokenEnhancer 的使用

TokenEnhancer 是一個增強器,JWT 中是可以放一些我們自定義的信息的,如果要加入一些我們自己的信息的話,就得使用 TokenEnhancer

還是修改 TokenStoreConfig ,在 JwtTokenConfig 這個內(nèi)部類中,加一個配置

@Bean
@ConditionalOnBean(TokenEnhancer.class)
public TokenEnhancer jwtTokenEnhancer(){
    return new MyJwtTokenEnhancer();
}

然后 MyJwtTokenEnhancer 代碼如下:

public class MyJwtTokenEnhancer implements TokenEnhancer { 
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        Map<String, Object> info = new HashMap<>(1);
        info.put("custom", "test");
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
        return accessToken;
    } 
}

這里加了 @ConditionalOnBean,是必須存在一個TokenEnhancer 的時候,才被創(chuàng)建, 之前的 JwtAccessTokenConverter 也是一個 TokenEnhancer

最后,認證服務(wù)器配置類 MyAuthorizationServerConfig 中,需要修改一下

@Autowired(required = false)
private TokenEnhancer jwtTokenEnhancer; 
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
 
    endpoints.authenticationManager(authenticationManager);
    endpoints.userDetailsService(userDetailsService);
    endpoints.tokenStore(tokenStore);
 
    // 只有配置使用JWT的時候才會生效
    if (jwtAccessTokenConverter != null && jwtTokenEnhancer != null) {
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> enhancers = new ArrayList<>();
        enhancers.add(jwtTokenEnhancer);
        enhancers.add(jwtAccessTokenConverter);
        enhancerChain.setTokenEnhancers(enhancers);
        endpoints.tokenEnhancer(enhancerChain)
                .accessTokenConverter(jwtAccessTokenConverter);
    }
}

測試

獲取token,然后解析結(jié)果如下:

自定義數(shù)據(jù)解析

這里 Spring 在解析JWT的時候會解析成一個 Authentication 對象,并不會解析我們上面設(shè)置的自定義字段,這個還需要我們自己去解析

demo 項目中增加一個 jwt 解析的依賴

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.7.0</version>
</dependency>

然后再 /user/me 這個接口中做解析,代碼如下:

@GetMapping("/me")
public Object me(Authentication authentication, HttpServletRequest request) throws UnsupportedEncodingException {
    // 從請求頭中獲取到token
    String jwtToken = StringUtils.substringAfter(request.getHeader("Authorization"), AUTHORIZATION_PREFIX);
    log.info("請求頭中的token:{}", jwtToken);
 
    // 獲取配置中的 jwtTokenSignKey
    String jwtTokenSignKey = securityProperties.getOAuth2().getJwtTokenSignKey();
    Claims claims = Jwts.parser().setSigningKey(jwtTokenSignKey.getBytes("UTF-8")).parseClaimsJws(jwtToken).getBody();
    return claims;
}

效果如下:

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java 實現(xiàn)截取字符串并按字節(jié)分別輸出實例代碼

    java 實現(xiàn)截取字符串并按字節(jié)分別輸出實例代碼

    這篇文章主要介紹了java 實現(xiàn)截取字符串并按字節(jié)分別輸出實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java格式化輸出printf()解讀

    Java格式化輸出printf()解讀

    這篇文章主要介紹了Java格式化輸出printf()解讀,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java實現(xiàn)UDP多線程在線咨詢

    Java實現(xiàn)UDP多線程在線咨詢

    這篇文章主要為大家詳細介紹了Java實現(xiàn)UDP多線程在線咨詢,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Spring中使用騰訊云發(fā)送短信驗證碼的實現(xiàn)示例

    Spring中使用騰訊云發(fā)送短信驗證碼的實現(xiàn)示例

    本文主要介紹了Spring?中?使用騰訊云發(fā)送短信驗證碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • JAVA mongodb 聚合幾種查詢方式詳解

    JAVA mongodb 聚合幾種查詢方式詳解

    這篇文章主要介紹了JAVA mongodb 聚合幾種查詢方式詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • JavaWeb Session失效時間設(shè)置方法

    JavaWeb Session失效時間設(shè)置方法

    這篇文章主要介紹了JavaWeb Session失效時間設(shè)置方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-12-12
  • java中常見的中文亂碼總結(jié)

    java中常見的中文亂碼總結(jié)

    本文主要介紹了java中常見的中文亂碼以及解決方法,主要包括字節(jié)碼文件讀取時出現(xiàn)的亂碼問題,本文通過實例代碼給大家介紹的非常詳細,具有很好的參考價值,感興趣的朋友跟隨小編一起看看吧
    2017-03-03
  • java利用Socket實現(xiàn)聊天室功能實例

    java利用Socket實現(xiàn)聊天室功能實例

    這篇文章主要介紹了java利用Socket實現(xiàn)聊天室功能實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • SpringBoot讀取配置優(yōu)先級順序的方法詳解

    SpringBoot讀取配置優(yōu)先級順序的方法詳解

    Spring Boot作為一種輕量級的Java應(yīng)用程序框架,以其開箱即用、快速搭建新項目的特性贏得了廣大開發(fā)者的青睞,在Spring Boot生態(tài)系統(tǒng)中,配置屬性可以從各種來源獲取,本文將深入探討Spring Boot加載外部配置屬性的優(yōu)先級規(guī)則,需要的朋友可以參考下
    2024-05-05
  • Schedule定時任務(wù)在分布式產(chǎn)生的問題詳解

    Schedule定時任務(wù)在分布式產(chǎn)生的問題詳解

    這篇文章主要介紹了Schedule定時任務(wù)在分布式產(chǎn)生的問題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10

最新評論