【MS】spring security oauth 2のRedisTokenStore追加ストリーム制限パラメータ保存


Spring security oauth 2のRedisTokenStore追加ストリーム制限パラメータ保存


前言
前に書いた『ゲートウェイspringcloud-gateway Tokenによるストリーム制限』では、ゲートウェイから要求されたtokenを取得し、tokenに基づいてredisに行ってストリーム制限パラメータを取得していますが、このパラメータはどこで保存されていますか?
そう、ユーザー認証の時、ストリーム制限パラメータをtokenと一緒にredisに保存しました
ダイレクトコード
1、CustomRedisTokenStoreクラスを作成する、つまり元のRedisTokenStoreのコードをコピーする
2つのメソッドを追加
  • setUserLimitLevel(OAuth2AccessToken token, OAuth2Authentication authentication)保存限流パラメータ
  • updateUserLimitLevel(StoreUser storeUser,String token)更新限流パラメータ
  • removeAccessToken()メソッドでも自分が追加したものも一緒にremoveすればいい
  • 
    public class CustomRedisTokenStore implements TokenStore {
    
        ....    
        
        
    	public void setUserLimitLevel(OAuth2AccessToken token, OAuth2Authentication authentication){
    		StoreUser storeUser = new StoreUser();
    		String grantType =  authentication.getOAuth2Request().getGrantType();
    		switch (grantType){
    			case SecurityConstants.CLIENT_CREDENTIALS:
    				storeUser.setLimitLevel(MapUtil.getInt(token.getAdditionalInformation(),SecurityConstants.LIMIT_LEVEL));
    				storeUser.setUserId(authentication.getOAuth2Request().getClientId());
    				storeUser.setUserName(authentication.getOAuth2Request().getClientId());
    				break;
    			default:
    				CustomUserDetailsUser customUser = (CustomUserDetailsUser) authentication.getPrincipal();
    				storeUser = StoreUser.builder().userId(customUser.getUserId()).limitLevel(customUser.getLimitLevel()).userName(customUser.getUsername()).build();
    				break;
    		}
    		byte[] serializedAuthUser = serialize(storeUser);
    		byte[] authUserKey = serializeKey(AUTH_USER + token.getValue());
    		RedisConnection conn = getConnection();
    		try {
    			if (springDataRedis_2_0) {
    				try {
    					this.redisConnectionSet_2_0.invoke(conn, authUserKey, serializedAuthUser);
    				} catch (Exception ex) {
    					throw new RuntimeException(ex);
    				}
    			} else {
    				conn.set(authUserKey, serializedAuthUser);
    			}
    
    			if (token.getExpiration() != null) {
    				int seconds = token.getExpiresIn();
    				conn.expire(authUserKey, seconds);
    			}
    			conn.closePipeline();
    		}finally {
    			conn.close();
    		}
    
    	}
    
    	public void updateUserLimitLevel(StoreUser storeUser,String token){
    		byte[] serializedAuthUser = serialize(storeUser);
    		byte[] authUserKey = serializeKey(AUTH_USER + token);
    		RedisConnection conn = getConnection();
    		try{
    			conn.openPipeline();
    			conn.set(authUserKey, serializedAuthUser);
    			conn.closePipeline();
    		}finally {
    			conn.close();
    		}
    	}
        
        ....    
    }
    
    

    2、beanを配置して自分で書いたCustomRedisTokenStoreを有効にする

        /**
         *   tokenStore   redis
         * @return
         */
        @Bean
        public TokenStore tokenStore() {
            CustomRedisTokenStore tokenStore = new CustomRedisTokenStore(redisConnectionFactory);
            tokenStore.setPrefix(SecurityConstants.MS_OAUTH_PREFIX);
            return tokenStore;
        }
    
    

    3、ユーザー検証後、データベースから検索したストリーム制限パラメータをsecurityのUserに添付する

  • 新しいクラスCustomUserDetailsUser securityを継承するuserクラス
  • UserDetailsServiceloadUserByUsernameメソッドは、いくつかのカスタムデータをCustomUserDetailsUserオブジェクトに配置し、
  • に戻る.
    /**
     * @Description //TODO           $
     * @Date 20:49
     * @Author [email protected]
     **/
    public class CustomUserDetailsUser extends User {
    
        @Getter
        @Setter
        public Integer userId;
        /**
         *     
         */
        @Getter
        @Setter
        private Integer limitLevel;
    
        public CustomUserDetailsUser(Integer userId,Integer limitLevel, String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
            super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
            this.userId = userId;
            this.limitLevel = limitLevel;
        }
    }
    
    

    4、TokenEnhancerインタフェースを書き換え、CustomUserDetailsUserに置かれたいくつかのカスタムパラメータをOAuth 2 Authenticationに入れ、TokenStoreでパラメータを取得してredisに保存する

    
    /**
     * @author czx
     * @title: CustomTokenEnhancer
     * @projectName ms
     * @description: TODO
     * @date 2019/7/2610:12
     */
    public class CustomTokenEnhancer implements TokenEnhancer {
    
        private CustomClientDetailsService customClientDetailsService;
    
        public CustomTokenEnhancer(CustomClientDetailsService customClientDetailsService){
            this.customClientDetailsService = customClientDetailsService;
        }
    
        @Override
        public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
            if (SecurityConstants.CLIENT_CREDENTIALS.equals(authentication.getOAuth2Request().getGrantType())) {
                ClientDetails clientDetails = customClientDetailsService.loadClientByClientId((String) authentication.getPrincipal());
                ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(clientDetails.getAdditionalInformation());
                return accessToken;
            }
    
            final Map<String, Object> additionalInfo = new HashMap<>(8);
            CustomUserDetailsUser customUserDetailsUser = (CustomUserDetailsUser) authentication.getUserAuthentication().getPrincipal();
            additionalInfo.put(SecurityConstants.USER_ID, customUserDetailsUser.getUserId());
            additionalInfo.put(SecurityConstants.LIMIT_LEVEL, customUserDetailsUser.getLimitLevel());
            additionalInfo.put(SecurityConstants.USER_NAME, customUserDetailsUser.getUsername());
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
            return accessToken;
        }
    }
    
    

    5、beanを配置し、書き換えたCustomTokenEnhancerを有効にする

        /**
         * token     。
         * @return TokenEnhancer
         */
        @Bean
        public TokenEnhancer tokenEnhancer() {
            return new CustomTokenEnhancer(customClientDetailsService());
        }
    
    

    これで完成!


    ソースゲート:https://github.com/yzcheng90/ms