In my spring application, I would like that a SecurityContext
always holds an Authentication
. If it's not a regular UsernamePasswordAuthenticationToken
, it will be a PreAuthenticatedAuthenticationToken
describing the "system user." This has reasons within different system function which requires a user. To avoid a special treatment if there is no user context, I merely want to add the system context. IMHO, this has also to do with the single responsibility principle.
To achieve this, I can simply implement my own SecurityContextHolderStrategy
and set the it to the SecurityContextHolder
with SecurityContextHolder.setStrategyName(MyStrategyClassName);
Now to the problem:
The default SecurityContextHolderStrategy
is the ThreadLocalSecurityContextHolderStrategy
. I'm happy with this strategy and how it works. The only thing which I would change is the getContext()
method.
public SecurityContext getContext() {
SecurityContext ctx = CONTEXT_HOLDER.get();
if (ctx == null) {
ctx = createEmptyContext();
CONTEXT_HOLDER.set(ctx);
}
return ctx;
}
to
public SecurityContext getContext() {
SecurityContext ctx = CONTEXT_HOLDER.get();
if (ctx == null) {
ctx = createEmptyContext();
Authentication authentication = new PreAuthenticatedAuthenticationToken("system", null);
authentication.setAuthenticated(true);
ctx.setAuthentication(authentication);
CONTEXT_HOLDER.set(ctx);
}
return ctx;
}
This is not possible as the ThreadLocalSecurityContextHolderStrategy
class is not public
. Of course I can simply copy paste the code of the ThreadLocalSecurityContextHolderStrategy
into my own SecurityContextHolderStrategy
and implement the getContext()
method the way I want. But this gives me the feeling as I might be on the wrong path.
How could I achieve a "system user" Authentication
as default for a new SecurityContext
?
Update
My approach above is apparently not a solution as it is extremely invasive, creates redundant code and needs special treatment within the web filter chain. But it should give an understanding of my goal. I'm looking for a solution, which fits as seamless as possible to the native spring security implementation. My problem is that I'm quite fixed on the invasive approach. How can this solve nicely? I cannot imagine that I'm the first person with this requirement. Or is the whole concept altogether wrong?