I try to enhance Spring-autoconfigured object mapper for (de)serialization of the Authentication
object. Here’s how I’m doing the deserialization (in the context of a Quartz job):
@Component
class MyJob : Job {
@Autowired
internal lateinit var objectMapper: ObjectMapper
override fun execute(context: JobExecutionContext) {
val loader = javaClass.classLoader
val modules = SecurityJackson2Modules.getModules(loader)
objectMapper.registerModules(modules)
val jobDataMap = context.jobDetail.jobDataMap
val context = objectMapper.readValue(jobDataMap["context"] as String, SecurityContextImpl::class.java)
SecurityContextHolder.setContext(context)
// other task code
}
}
The jobDataMap["context"]
contains serialized Authentication
which looks like this
{
"@class" : "org.springframework.security.core.context.SecurityContextImpl",
"authentication" : {
"@class" : "org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken",
"authorities" : [ "java.util.Collections$UnmodifiableRandomAccessList", [ {
"@class" : "org.springframework.security.core.authority.SimpleGrantedAuthority",
"authority" : "ROLE_Corporate_CLIENT"
} ] ],
"details" : {
"@class" : "org.springframework.security.web.authentication.WebAuthenticationDetails",
"remoteAddress" : "127.0.0.1"
},
"authenticated" : true,
"principal" : {
"@class" : "my.package.UserInfo",
"origin" : "EXTERNAL",
"subject" : "9007-04-19-08.06.54.856184",
"displayName" : "9007-04-19-08.06.54.856184",
"roles" : [ "java.util.Collections$SingletonList", [ "Corporate_CLIENT" ] ]
},
"credentials" : "9007-04-19-08.06.54.856184"
}
}
To deseriliaze the @class
“annotated” objects I need special Spring security mixins which should be provided by registering the SecurityJackson2Modules
. And indeed debugging shows that they are really registered in the objectMapper
(see e.g. the SimpleGrantedAuthority
entry).
Yet, the objectMapper.readValue
fails to deserialize this snippet
{"@class":"org.springframework.security.core.authority.SimpleGrantedAuthority","authority":"ROLE_Corporate_CLIENT"}
into a SimpleGrantedAuthority
instance. Instead, it probably ignores the registered mixin and just deserializes it into a HashMap
.
What am I missing?