如何在JASPIC中保存经过身份validation的用户?

我开发了一个安全validation模块(SAM)并实现了validateRequest方法。 我还有一个简单的webapp配置为使用此SAM。

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

 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);

 2015-05-05 11:21:02,200 DEBUG nmjsSaml2AuthModule [http-listener-1(2)] Client: Subject: 

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

编辑我想通过手动将它存储在HttpSession找到了一种方法: req.getSession().setAttribute("subject", user); 不漂亮,但它的工作原理。

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

是的,尽管JASPIC被设计为无状态,但它确实可以选择半自动记住登录。

然而,该选项并不比仅在会话中存储细节并在每个请求开始时重新进行身份validation的代码少得多。

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

 messageInfo.getMap().put("javax.servlet.http.registerSession", TRUE.toString()); 

然后在每个请求开始时仍然会调用您的身份validation模块(SAM),但您可以执行以下“协议”来重新使用存储的身份数据(用户名+角色):

 HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage(); Principal userPrincipal = request.getUserPrincipal(); if (userPrincipal != null) { handler.handle(new Callback[] { new CallerPrincipalCallback(clientSubject, userPrincipal) } ); return SUCCESS; } 

我写了一篇博客文章 ,里面有更多细节。 您可以在Java EE 7示例项目中找到使用完全可用示例的测试。

遗憾的是,只要(http)会话有效,JASPIC中就没有任何function可以说你根本不想要调用SAM。

如果您关心此function,请投票支持以下问题: https : //java.net/jira/browse/JASPIC_SPEC-20

我想通过手动将它存储在HttpSession中找到了一种方法:req.getSession()。setAttribute(“subject”,user); 不漂亮,但它的工作原理。

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

我上面展示的方法并不是真的不同于此,但除了明显的差异(一个回调与两个回调,从请求中获取主体而不是从会话中获取)主要区别在于通过半自动方式容器是可以自由使用它存储数据的任何机制。

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