在我的 spring 应用程序中,我希望 aSecurityContext始终持有一个Authentication. 如果它不是一个常规的UsernamePasswordAuthenticationToken,它将是一个PreAuthenticatedAuthenticationToken描述“系统用户”。这在需要用户的不同系统功能中是有原因的。如果没有用户上下文,为了避免特殊处理,我只想添加系统上下文。恕我直言,这也与单一责任原则有关。
为此,我可以简单地实现我自己的SecurityContextHolderStrategy并将其设置为SecurityContextHolderwithSecurityContextHolder.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 安全实现相匹配。我的问题是我对侵入性方法非常固定。这怎么能很好地解决?我无法想象我是第一个有这个要求的人。还是整个概念完全错误?