首页 > 解决方案 > Spring Security OAuth2 - 如何修改令牌响应 JSON?

问题描述

我收到如下响应 JSON(用于 JWT 令牌请求):

{
    "access_token": "<JWT Access Token>",
    "token_type": "bearer",
    "refresh_token": "<JWT Refresh Token>",
    "expires_in": 3599,
    "scope": "read write trust",
    "DateOfBirth": "01-01-1990",
    "Address_Line_1": "ABCD Andrews Dr, Apt 111",
    "PAN_Number": "12345ABCD",
    "Address_Line_2": "Dublin, CA 94588",
    "jti": "e6a19730-e4e5-4cec-bf59-bd90ca1acc34"
}

我想将它(通过删除一些元素)修改为:

{
    "access_token": "<JWT Access Token>",
    "token_type": "bearer",
    "refresh_token": "<JWT Refresh Token>",
    "expires_in": 3599,
    "scope": "read write trust",
    "jti": "e6a19730-e4e5-4cec-bf59-bd90ca1acc34"
}

我尝试按照一些人的建议使用 ResponseBodyAdvice。但问题是响应主体对象(可作为公共对象 beforeBodyWrite(Object body ...) 是对象类型 - “org.springframework.security.oauth2.common.DefaultOAuth2AccessToken”而不是 JSON。我不确定如何操作 DefaultOAuth2AccessToken删除附加元素。

有人可以帮我吗?

public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
        configurer
                .inMemory()
                .withClient(CLIEN_ID)
                .secret(passwordEncoder().encode(CLIENT_SECRET))
                .authorizedGrantTypes(GRANT_TYPE_PASSWORD, REFRESH_TOKEN)
                .scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
                .accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS)
                .refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS);
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }


    @Override
    public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), accessTokenConverter()));
        endpoints.tokenStore(tokenStore()).tokenEnhancer(tokenEnhancerChain).authenticationManager(authenticationManager);
    }

    @Bean
    public TokenEnhancer tokenEnhancer() {
        return new CustomTokenEnhancer();
    }
}
public class CustomTokenEnhancer implements TokenEnhancer {
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
        Map<String, Object> additionalInfo = new HashMap<>();
        additionalInfo.put("DateOfBirth", oAuth2Authentication.getOAuth2Request().getRequestParameters().get("dob"));
        additionalInfo.put("PAN_Number", oAuth2Authentication.getOAuth2Request().getRequestParameters().get("pan"));
        additionalInfo.put("Address_Line_1", oAuth2Authentication.getOAuth2Request().getRequestParameters().get("addr1"));
        additionalInfo.put("Address_Line_2", oAuth2Authentication.getOAuth2Request().getRequestParameters().get("addr2"));
        ((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(additionalInfo);
        return oAuth2AccessToken;
    }
}
@ControllerAdvice
public class ResponseJSONAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends
    HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        /*
          Logic to remove additional elements from response JSON.
          But Object body is of type org.springframework.security.oauth2.common.DefaultOAuth2AccessToken and not JSON!!
        */
        return body;
    }
}

标签: spring-security-oauth2

解决方案


继续使用 ResponseBodyAdvice,首先定义一个包含所有要显示的字段的类。然后让方法 beforeBodyWrite 返回该类。在 beforeBodyWrite 方法中,您想通过 body 的值设置定义类的字段,然后返回它。

抱歉我英语不好,不懂就问我;)

public BaseResponse beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends     HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        BaseResponse res = new BaseResponse();
        res.setResponseStatusCode(StatusResponse.SUCCESS.getCode()); 
        res.setResponseStatusMessage(StatusResponse.SUCCESS.getName()); 
        res.setContent(body);
        return res;
}

推荐阅读