我现在正通过尝试从Keycloak迁移到Spring Authorization Server来与JSON反序列化斗争一段时间(我仍然怀疑这是否是一个好主意)。
首先尝试使用代码授权类型获取访问令牌,在使用CustomUserDetails时出现了异常
Caused by: java.lang.IllegalArgumentException: The class with com.company.user.CustomUserDetails and name of com.company.user.CustomUserDetails is not in the allowlist. If you believe this class is safe to deserialize, please provide an explicit mapping using Jackson annotations or by providing a Mixin. If the serialization is only done by a trusted source, you can also enable default typing. See https://github.com/spring-projects/spring-security/issues/4370 for details
我访问了https://github.com/spring-projects/spring-security/issues/4370链接,但没有什么真正有用的。
根据错误消息,我定义了此CustomUserDetailsMixin
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonDeserialize(using = CustomUserDetailsSerializer.class)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class CustomUserDetailsMixin {
}
CustomUserDetailsSerializer
:
public class CustomUserDetailsSerializer extends JsonDeserializer<CustomUserDetails> {
private static final TypeReference<Set<SimpleGrantedAuthority>> SIMPLE_GRANTED_AUTHORITY_SET = new TypeReference<>() {
};
@Override
public CustomUserDetails deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
JsonNode jsonNode = mapper.readTree(jp);
//there is an issue here :
Set<? extends GrantedAuthority> authorities = mapper.convertValue(jsonNode.get("authorities"), SIMPLE_GRANTED_AUTHORITY_SET);
}
}
在这里注册:
@Configuration(proxyBeanMethods = false)
public class AuthorizationServerConfiguration {
@Bean
public OAuth2AuthorizationService oAuth2AuthorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
JdbcOAuth2AuthorizationService oAuth2AuthorizationService = new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);
JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper rowMapper = new JdbcOAuth2AuthorizationService.OAuth2AuthorizationRowMapper(registeredClientRepository);
ClassLoader classLoader = JdbcOAuth2AuthorizationService.class.getClassLoader();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModules(new CoreJackson2Module());
objectMapper.registerModules(SecurityJackson2Modules.getModules(classLoader));
objectMapper.registerModule(new OAuth2AuthorizationServerJackson2Module());
//registering the mixin
objectMapper.addMixIn(CustomUserDetails.class, CustomUserDetailsMixin.class);
rowMapper.setObjectMapper(objectMapper);
oAuth2AuthorizationService.setAuthorizationRowMapper(rowMapper);
return oAuth2AuthorizationService;
}
}
但现在我又犯了一个错误:
java.lang.IllegalArgumentException: Could not resolve type id 'java.util.ImmutableCollections$ListN' as a subtype of `java.util.Set<org.springframework.security.core.authority.SimpleGrantedAuthority>`: Not a subtype
at [Source: UNKNOWN; byte offset: #UNKNOWN]
at org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService$OAuth2AuthorizationRowMapper.parseMap(JdbcOAuth2AuthorizationService.java:467)
我看了一下spring security保存在db中的JSON,它看起来像这样:
{
"@class": "java.util.Collections$UnmodifiableMap",
"java.security.Principal": {
"@class": "org.springframework.security.authentication.UsernamePasswordAuthenticationToken",
"authorities": [
"java.util.Collections$UnmodifiableRandomAccessList",
[
{
"@class": "org.springframework.security.core.authority.SimpleGrantedAuthority",
"authority": "ROLE_USER"
}
]
],
}
....
}
问题是如何解决最后一个错误?
1条答案
按热度按时间mefy6pfw1#
json中的“java.util.Collections$UnmodifiableRandomAccessList”类型信息与您的SIMPLE_GRANTED_AUTHORITY_SET类型引用不兼容,因此有一种简单的方法来处理。
使用已经在CoreJackson 2 Module中注册的类型引用,然后将其转换为实际需要的类型。