Java 如何在JASPIC中保存经过身份验证的用户?

Java 如何在JASPIC中保存经过身份验证的用户?,java,security,authentication,jaspic,jsr196,Java,Security,Authentication,Jaspic,Jsr196,我开发了一个安全认证模块(SAM),并实现了validateRequest方法。我还配置了一个简单的webapp来使用这个SAM 在我的validateRequest方法中,我检查clientSubject并使用硬编码用户名设置CallerPrincipalCallback,使用硬编码组名设置GroupPrincipalCallback: final CallerPrincipalCallback callerPrincipalCallback = new CallerPrincipalCall

我开发了一个安全认证模块(SAM),并实现了
validateRequest
方法。我还配置了一个简单的webapp来使用这个SAM

在我的
validateRequest
方法中,我检查clientSubject并使用硬编码用户名设置
CallerPrincipalCallback
,使用硬编码组名设置
GroupPrincipalCallback

final CallerPrincipalCallback callerPrincipalCallback = new CallerPrincipalCallback(clientSubject, "anonymous");
final GroupPrincipalCallback groupPrincipalCallback = new GroupPrincipalCallback(clientSubject, new String[] {"user"});

try {
  this.handler.handle(new Callback[] {callerPrincipalCallback, groupPrincipalCallback});
} catch (IOException | UnsupportedCallbackException e) {
  logger.error(e.getMessage());
}
我注意到,每次我在我的webapp中刷新servlet时,客户机主题都是空的,
logger.debug(“client:{}”,clientSubject)

是否有可能以某种方式“保存”一个主题,以便将该主题附加到会话,并且我每次都可以跳过登录同一用户

编辑我想我找到了一种方法,手动将其存储在
HttpSession
中:
req.getSession().setAttribute(“主题”,用户)不漂亮,但它可以工作

是否有可能以某种方式“保存”一个主题,以便将该主题附加到会话,并且我每次都可以跳过登录同一用户

是的,尽管JASPIC被设计成无状态,但它确实有一个半自动记住登录的选项

但是,与在会话中存储详细信息并在每个请求开始时重新验证相比,此选项实际上并不是更少的代码

方法是首先在消息信息映射中设置一个布尔值,然后返回成功并退出
validateRequest

messageInfo.getMap().put("javax.servlet.http.registerSession", TRUE.toString());
然后在每个请求开始时,仍会调用您的身份验证模块(SAM),但您可以执行以下“协议”以重用存储的身份数据(用户名+角色):

我写了一篇有更多细节的文章。您可以在中找到一个使用完整工作示例的测试

不幸的是,JASPIC中没有任何功能可以说只要(http)会话有效,就根本不想调用SAM

如果您喜欢此功能,请投票支持以下问题:

我想我找到了一种方法,将它手动存储在HttpSession中:req.getSession().setAttribute(“subject”,user);虽然不漂亮,但很管用

或多或少的“官方”方法是将用户名和角色存储在会话中,然后在每次调用
validateRequest
时检查此数据是否存在,如果存在,则将其交给两个回调

我上面展示的方法与此并没有什么不同,但除了明显的区别(一个回调与两个回调,从请求中获取主体与从会话中获取主体)之外,主要的区别在于,通过半自动的方式,容器可以自由地使用它必须使用的任何机制来存储数据


这可能只是会话中的一个属性(一个简单的JASPIC实现肯定可以做到这一点),或者它可以使用大多数容器所拥有的会话的某些隐藏部分。用户代码无法直接访问此隐藏部分,这可能有一些好处。

谢谢,Arjan,我知道您对此非常了解(从您那里找到了很多博客文章),并且正在寻找一种联系方式。很高兴你找到了我。:)@大卫:不客气,希望答案有帮助;)非常有帮助,我很高兴我不是唯一一个认为这是当前规范中的遗漏的人,我来投票。@Davio你使用gf4.0还是4.1?我们将它与4.1一起使用,它是有效的。我记得以前的一个版本有一个bug,但它不起作用。感谢Arjan的帖子和评论。这是我一直在寻找的一步。
messageInfo.getMap().put("javax.servlet.http.registerSession", TRUE.toString());
HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
Principal userPrincipal = request.getUserPrincipal();

if (userPrincipal != null) {   
    handler.handle(new Callback[] { 
        new CallerPrincipalCallback(clientSubject, userPrincipal) }
    );

    return SUCCESS;   
}