中间件国产化-Redis=>TongRDS
由于项目需要, 需要将原项目中间件国产化, 其中Redis需要国产化为TongRDS;整个配置过程很简单, 就是集成oauth2的时候出了序列化问题, 提供商已经修改了这个bug, 所以不能完整提供数据; 在提供商没有修改这个bug之前,需要更改默认的序列化方式;
1.更改token序列化方式
@Configuration public class MyTokenStoreConfig { @Autowired private RedisConnectionFactory redisConnectionFactory; @Bean public TokenStore tokenStore() { RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory); redisTokenStore.setSerializationStrategy(new FastjsonRedisTokenStoreSerializationStrategy()); return redisTokenStore; } }复制代码
2.自定义序列化策略
public class FastjsonRedisTokenStoreSerializationStrategy implements RedisTokenStoreSerializationStrategy { private static ParserConfig config = new ParserConfig(); static { init(); } protected static void init() { //自定义oauth2序列化:DefaultOAuth2RefreshToken 没有setValue方法,会导致JSON序列化为null config.setAutoTypeSupport(true);//开启AutoType //自定义DefaultOauth2RefreshTokenSerializer反序列化 config.putDeserializer(DefaultOAuth2RefreshToken.class, new DefaultOauth2RefreshTokenSerializer()); //自定义OAuth2Authentication反序列化 config.putDeserializer(OAuth2Authentication.class, new OAuth2AuthenticationSerializer()); //添加autotype白名单 config.addAccept("org.springframework.security.oauth2.provider."); config.addAccept("org.springframework.security.oauth2.provider.client"); TypeUtils.addMapping("org.springframework.security.oauth2.provider.OAuth2Authentication", OAuth2Authentication.class); TypeUtils.addMapping("org.springframework.security.oauth2.provider.client.BaseClientDetails", BaseClientDetails.class); config.addAccept("org.springframework.security.oauth2.common."); TypeUtils.addMapping("org.springframework.security.oauth2.common.DefaultOAuth2AccessToken", DefaultOAuth2AccessToken.class); TypeUtils.addMapping("org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken", DefaultExpiringOAuth2RefreshToken.class); config.addAccept("org.springframework.security.web.authentication.preauth"); TypeUtils.addMapping("org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken", PreAuthenticatedAuthenticationToken.class); } @Override public <T> T deserialize(byte[] bytes, Class<T> aClass) { Preconditions.checkArgument(aClass != null, "clazz can't be null"); if (bytes == null || bytes.length == 0) { return null; } try { return JSON.parseObject(new String(bytes, IOUtils.UTF8), aClass, config); } catch (Exception ex) { throw new SerializationException("Could not serialize: " + ex.getMessage(), ex); } } @Override public String deserializeString(byte[] bytes) { if (bytes == null || bytes.length == 0) { return null; } return new String(bytes, IOUtils.UTF8); } @Override public byte[] serialize(Object o) { if (o == null) { return new byte[0]; } try { return JSON.toJSONBytes(o, SerializerFeature.WriteClassName, SerializerFeature.DisableCircularReferenceDetect); } catch (Exception ex) { throw new SerializationException("Could not serialize: " + ex.getMessage(), ex); } } @Override public byte[] serialize(String data) { if (data == null || data.length() == 0) { return new byte[0]; } return data.getBytes(Charset.forName("utf-8")); } }复制代码
3.序列化方式
public class DefaultOauth2RefreshTokenSerializer implements ObjectDeserializer { @Override public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { if (type == DefaultOAuth2RefreshToken.class) { JSONObject jsonObject = parser.parseObject(); String tokenId = jsonObject.getString("value"); DefaultOAuth2RefreshToken refreshToken = new DefaultOAuth2RefreshToken(tokenId); return (T) refreshToken; } return null; } @Override public int getFastMatchToken() { return 0; } }复制代码
public class OAuth2AuthenticationSerializer implements ObjectDeserializer { @Override public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { if (type == OAuth2Authentication.class) { try { Object o = parse(parser); if (o == null) { return null; } else if (o instanceof OAuth2Authentication) { return (T) o; } JSONObject jsonObject = (JSONObject) o; OAuth2Request request = parseOAuth2Request(jsonObject); //判断json节点userAuthentication的类型,根据类型动态取值 //UsernamePasswordAuthenticationToken 密码模式/授权码模式下,存储类型为UsernamePasswordAuthenticationToken //PreAuthenticatedAuthenticationToken 刷新token模式下,存储类型为PreAuthenticatedAuthenticationToken Object autoType = jsonObject.get("userAuthentication"); return (T) new OAuth2Authentication(request, jsonObject.getObject("userAuthentication", (Type) autoType.getClass())); } catch (Exception e) { e.printStackTrace(); } return null; } return null; } private OAuth2Request parseOAuth2Request(JSONObject jsonObject) { JSONObject json = jsonObject.getObject("oAuth2Request", JSONObject.class); Map<String, String> requestParameters = json.getObject("requestParameters", Map.class); String clientId = json.getString("clientId"); String grantType = json.getString("grantType"); String redirectUri = json.getString("redirectUri"); Boolean approved = json.getBoolean("approved"); Set<String> responseTypes = json .getObject("responseTypes", new TypeReference<HashSet<String>>() { }); Set<String> scope = json.getObject("scope", new TypeReference<HashSet<String>>() { }); Set<String> authorities = json.getObject("authorities", new TypeReference<HashSet<String>>() { }); Set<GrantedAuthority> grantedAuthorities = new HashSet<>(0); if (authorities != null && !authorities.isEmpty()) { authorities.forEach(s -> grantedAuthorities.add(new SimpleGrantedAuthority(s))); } Set<String> resourceIds = json .getObject("resourceIds", new TypeReference<HashSet<String>>() { }); Map<String, Serializable> extensions = json .getObject("extensions", new TypeReference<HashMap<String, Serializable>>() { }); OAuth2Request request = new OAuth2Request(requestParameters, clientId, grantedAuthorities, approved, scope, resourceIds, redirectUri, responseTypes, extensions); TokenRequest tokenRequest = new TokenRequest(requestParameters, clientId, scope, grantType); request.refresh(tokenRequest); return request; } @Override public int getFastMatchToken() { return 0; } private Object parse(DefaultJSONParser parse) { JSONObject object = new JSONObject(parse.lexer.isEnabled(Feature.OrderedField)); Object parsedObject = parse.parseObject((Map) object); if (parsedObject instanceof JSONObject) { return (JSONObject) parsedObject; } else if (parsedObject instanceof OAuth2Authentication) { return parsedObject; } else { return parsedObject == null ? null : new JSONObject((Map) parsedObject); } } }复制代码
参照: blog.csdn.net/lki_suidong…
作者:不懂不懂丶
链接:https://juejin.cn/post/7025535581882941476