自定义spring security oauth /auth/token的返回内容格式

场景

在前后端分离的项目中,一般后端返回给前端的格式是一个固定的json格式。

在这个前提下,spring security oauth 生成access token的请求/auth/token的返回内容就需要自定义

原返回值

我们希望使用我们自己固定的json格式

需求

我们的BaseResponse类

public class BaseResponse {

    private String errorcode;

    private String value;

    public String getErrorcode() {
        return errorcode;
    }

    public void setErrorcode(String errorcode) {
        this.errorcode = errorcode;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

Response类

@Data
public class Response extends BaseResponse{

    private Object data;

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

 

解决方案

先看源码,这些内容是如何返回的

org.springframework.security.oauth2.provider.endpoint.TokenEndpoint#postAccessToken

return new ResponseEntity<OAuth2AccessToken>(accessToken, headers, HttpStatus.OK);

那么我们的思路是写一个切面,将这个ResponseEntity进行重新组织就可以了。

步骤

1. 定义一个Serializer

public class ResponseSerializer extends StdSerializer<Response> {

    public ResponseSerializer() {
        super(Response.class);
    }

    @Override
    public void serialize(Response value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        OAuth2AccessToken oAuth2AccessToken = (OAuth2AccessToken) value.getData();
        gen.writeStartObject();
        gen.writeStringField("errorcode", value.getErrorcode());
        gen.writeStringField("value", value.getValue());

        gen.writeObjectFieldStart("data");
        gen.writeStringField("access_token", oAuth2AccessToken.getValue());
        gen.writeStringField("token_type", oAuth2AccessToken.getTokenType());
        gen.writeStringField("refresh_token", oAuth2AccessToken.getRefreshToken().getValue());
        gen.writeNumberField("expires_in",oAuth2AccessToken.getExpiresIn());
        gen.writeStringField("scope",oAuth2AccessToken.getScope().toString());
        gen.writeStringField("company",oAuth2AccessToken.getAdditionalInformation().get("company").toString());
        gen.writeStringField("jti",oAuth2AccessToken.getAdditionalInformation().get("jti").toString());
        gen.writeEndObject();

        gen.writeEndObject();
    }
}

2. 给Response类加入@JsonSerializer注解

@JsonSerialize(using = ResponseSerializer.class)
@Data
public class Response extends BaseResponse{

    private Object data;

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

3. 写一个切面来改变返回值

@Component
@Aspect
public class AuthTokenAspect {

    private Logger logger = LoggerFactory.getLogger(getClass());

    /// @Around是可以改变controller返回值的
    @Around("execution(* org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(..))")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
        // 放行
        Response response = new Response();
        Object proceed = pjp.proceed();
        if (proceed != null) {
            ResponseEntity<OAuth2AccessToken> responseEntity = (ResponseEntity<OAuth2AccessToken>)proceed;
            OAuth2AccessToken body = responseEntity.getBody();
            if (responseEntity.getStatusCode().is2xxSuccessful()) {
                response.setErrorcode(ErrorCode.OK.value);
                response.setValue(ErrorCode.OK.memo);
                response.setData(body);
            } else {
                logger.error("error:{}", responseEntity.getStatusCode().toString());
                response.setErrorcode(ErrorCode.ERROR.value);
                response.setValue("获取授权码失败");
            }
        }
        return ResponseEntity
                .status(200)
                .body(response);
    }
}

最终的效果

参考:Spring Security Oauth2 自定义 OAuth2 Exception

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值