• 使用fastjson时spring security oauth2获取token格式变化


    1.问题

    使用下面请求获取token时

    http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=123456

    预期返回值

    {
        "access_token": "b0f73d20-1c74-43f6-991d-3b4ca74fc4d4",
        "token_type": "bearer",
        "expires_in": 41374,
        "scope": "select"
    }

    但是返回值为

    {
    "expiration": 1513752144897,
    "expired": false,
    "expiresIn": 604799,
    "refreshToken": {
    "expiration": 1515739344897,
    "value": "dae50004-939c-40f2-98d8-4882374e08c7"
    },
    "scope": [
    "api"
    ],
    "tokenType": "bearer",
    "value": "1e2c4181-01be-4aa1-8042-c2d2f74008d0"
    }

    2.原因

    使用fastjson而不是默认的Jackson

    3.解决方法

    新写OAuth2AccessTokenMessageConverter类

    public class OAuth2AccessTokenMessageConverter extends AbstractHttpMessageConverter<OAuth2AccessToken> {
    
        private final FastJsonHttpMessageConverter delegateMessageConverter;
    
        public OAuth2AccessTokenMessageConverter() {
            super(MediaType.APPLICATION_JSON);
            this.delegateMessageConverter = new FastJsonHttpMessageConverter();
        }
    
        @Override
        protected boolean supports(Class<?> clazz) {
            return OAuth2AccessToken.class.isAssignableFrom(clazz);
        }
    
        @Override
        protected OAuth2AccessToken readInternal(Class<? extends OAuth2AccessToken> clazz, HttpInputMessage inputMessage)
                throws IOException, HttpMessageNotReadableException {
            throw new UnsupportedOperationException(
                    "This converter is only used for converting from externally aqcuired form data");
        }
    
        @Override
        protected void writeInternal(OAuth2AccessToken accessToken, HttpOutputMessage outputMessage) throws IOException,
                HttpMessageNotWritableException {
            Map<String, Object> data = new HashMap<>(8);
            data.put(OAuth2AccessToken.ACCESS_TOKEN, accessToken.getValue());
            data.put(OAuth2AccessToken.TOKEN_TYPE, accessToken.getTokenType());
            data.put(OAuth2AccessToken.EXPIRES_IN, accessToken.getExpiresIn());
            data.put(OAuth2AccessToken.SCOPE, String.join(" ", accessToken.getScope()));
            OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
            if (Objects.nonNull(refreshToken)) {
                data.put(OAuth2AccessToken.REFRESH_TOKEN, refreshToken.getValue());
            }
            delegateMessageConverter.write(data, MediaType.APPLICATION_JSON, outputMessage);
        }
    
    }

    加入MessageConverters

    @Configuration
    public class Oauth2WebMvcConfigurer implements WebMvcConfigurer {
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
           converters.add(0, new FastJsonHttpMessageConverter());
           converters.add(0, new OAuth2AccessTokenMessageConverter());
        }
    }

    4.参考文档

    参考FelixFly回答 https://github.com/alibaba/fastjson/issues/1640

    https://blog.csdn.net/yuelangyc/article/details/88235639

  • 相关阅读:
    安装vs2012后sql2008配置管理出错
    教你台式机如何接双显示器
    去除Office 2010的右键“共享文件夹同步”菜单
    内网的用户不能用外网IP访问内网
    VMware Workstation 8的简明使用教程
    EntityFramework4.0中遇到New transaction is not allowed because there are other threads running in the session
    几条软件开发心得
    .net各版本反射多种方法介绍
    .net4.0下的Lazy<T>类型简单应用
    使用DebugView小工具调试已部署的.net程序
  • 原文地址:https://www.cnblogs.com/SmilingEye/p/13391651.html
Copyright © 2020-2023  润新知