Spring Security OAuth2-如何修改令牌响应JSON?

时间:2019-01-31 08:35:57

标签: spring-security-oauth2

我正在获取响应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。但是问题是响应主体对象(作为public Object 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;
    }
}

2 个答案:

答案 0 :(得分:0)

从我的角度来看,您必须调整在AuthorizationServerConfigurerAdapter中配置的令牌增强功能 在方法

  public void configure(
  AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
    tokenEnhancerChain.setTokenEnhancers(
      Arrays.asList(tokenEnhancer(), accessTokenConverter()));

    endpoints.tokenStore(tokenStore())
             .tokenEnhancer(tokenEnhancerChain)
             .authenticationManager(authenticationManager);
}

您可以设置自定义增强或配置之一。这应该允许您打开或关闭使用令牌发送的内容

答案 1 :(得分:0)

继续使用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;
}