4

我开发了一个安全认证模块 (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());
}

我注意到每次在我的 web 应用程序中刷新 servlet 时,客户端主题都是空白的,logger.debug("Client: {}", clientSubject);

2015-05-05 11:21:02,200 DEBUG n.m.j.s.Saml2AuthModule [http-listener-1(2)] Client: Subject:

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

编辑我想我找到了一种方法,方法是手动将其存储在HttpSessionreq.getSession().setAttribute("subject", user);不漂亮,但它有效。

4

1 回答 1

6

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

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

然而,这个选项的代码并不比仅仅在会话中存储详细信息并在每个请求开始时重新验证要少得多。

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

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

然后在每个请求开始时仍会调用您的身份验证模块 (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 中就没有任何功能可以说明您根本不想调用 SAM。

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

我想我通过手动将其存储在 HttpSession 中找到了一种方法: req.getSession().setAttribute("subject", user); 不漂亮,但它有效。

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

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

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

于 2015-05-05T21:59:15.660 回答