在我的 spring 应用程序中,我希望 aSecurityContext
始终持有一个Authentication
. 如果它不是一个常规的UsernamePasswordAuthenticationToken
,它将是一个PreAuthenticatedAuthenticationToken
描述“系统用户”。这在需要用户的不同系统功能中是有原因的。如果没有用户上下文,为了避免特殊处理,我只想添加系统上下文。恕我直言,这也与单一责任原则有关。
为此,我可以简单地实现我自己的SecurityContextHolderStrategy
并将其设置为SecurityContextHolder
withSecurityContextHolder.setStrategyName(MyStrategyClassName);
现在解决问题:
默认SecurityContextHolderStrategy
值为 ThreadLocalSecurityContextHolderStrategy
. 我对这个策略及其运作方式感到满意。我唯一要改变的是getContext()
方法。
public SecurityContext getContext() {
SecurityContext ctx = CONTEXT_HOLDER.get();
if (ctx == null) {
ctx = createEmptyContext();
CONTEXT_HOLDER.set(ctx);
}
return ctx;
}
到
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;
}
这是不可能的,因为ThreadLocalSecurityContextHolderStrategy
类不是public
。当然,我可以简单地将代码复制粘贴ThreadLocalSecurityContextHolderStrategy
到我自己的代码中,SecurityContextHolderStrategy
然后按照我想要的方式实现该getContext()
方法。但这给了我一种感觉,因为我可能走错了路。
我如何才能将“系统用户”Authentication
作为新用户的默认设置SecurityContext
?
更新
我上面的方法显然不是一个解决方案,因为它极具侵入性,会创建冗余代码并且需要在 Web 过滤器链中进行特殊处理。但它应该让我了解我的目标。我正在寻找一种解决方案,该解决方案尽可能无缝地与本机 Spring 安全实现相匹配。我的问题是我对侵入性方法非常固定。这怎么能很好地解决?我无法想象我是第一个有这个要求的人。还是整个概念完全错误?