使用 JASPIC 进行身份验证时,web.xml 在身份验证方面是否仍然相关?

When using JASPIC for authentication, is web.xml still relevant in terms of authentication?

自从我完成 JASPIC 工作以来已经很久了。

我有一个 web.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>service-broker-related-resources</web-resource-name>
      <url-pattern>/v2/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>emcc</role-name>
    </auth-constraint>
  </security-constraint>

  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Frob Service Broker</realm-name>
  </login-config>

  <security-role>
    <role-name>emcc</role-name>
  </security-role>

</web-app>

我还设置并安装了服务器身份验证模块 (SAM)。在我的glassfish-web.xml中是这样提到的:

<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app httpservlet-security-provider="emccSAM">

我的 SAM 工作正常。

事实上,它的效果有点太好了!它正在拦截所有请求,而不仅仅是由 /v2/*<url-pattern> 标识的请求。这最初让我感到惊讶。

但是当我认真思考这个问题时,我认为这有一定的道理:SAM 现在负责身份验证,而不是容器,真的。

那么 web.xml 现在基本上不相关了吗?

然后我又想了想,显然它是相关的,因为它的内容还说明了身份验证发生后要做什么,即如果用户通过 SAM 成功验证,现在检查她是否有 emcc作用。如果她不这样做,并且请求可能以 /v2/ 开头,那么我们将她引导出去。如果她不这样做,并且大概是请求以其他任何内容开头,那么我们会让她加入。

那么,这是预期的行为吗,我的 SAM 必须自行有效地决定传入的请求是否值得验证? 我希望我的 SAM 会被触发"normally",即仅当有人尝试访问需要身份验证的 URI 时,如 <security-constraint>.

所述

可能值得注意的是,当 JAX-RS Application class 被注释为 @ApplicationPath("/v2") 时,唯一运行的 servlet 是默认安装的。

SAM 确实完全负责身份验证。它可能尊重声明性配置,但不是必需的。它甚至可以完全自行执行 Servlet 请求的授权(尽管这样做会超出其合同范围)。

根据 JASPIC 规范的第 3.8.3 节,强制要求在配置的 ServerAuthContext 上调用 validateRequest(因此在这种情况下它也是单个封装的 SAM)"on every request that satisfies the corresponding connection requirements".

如果 SAM 希望知道 Servlet 端点是否应该在描述符或注释方面被视为 "protected",它可以在 request [=14] 上调用 isMandatory =] 参数在初始化时中继给它,或者在消息验证时探测,MessageInfo 参数的映射是否存在 "javax.security.auth.message.MessagePolicy.isMandatory" 键和等于 Boolean.valueOf(value).booleanValue() == true 的映射值(规范§ 3.8.1.1).

最后但同样重要的是——声明性安全约束与授权无关吗?首先,我不确定各种规格是否适合 SAM 分配未声明的角色。除此之外,我还没有尝试过这个,所以我现在只能猜测并提供一个模糊的答案。我对此的看法是,它或多或少与身份验证提供商的情况相同。您实质上是在远离 AS 承担配置提供者的责任,因此您必须以某种方式进行补偿,即提供替代配置接口。说授权由一些 JACC 提供者管理。如果它是默认的、AS 提供的,在没有声明性安全约束的情况下,它会无法承认调用者需要处于 "emcc" 角色才能访问 /v2/* 的事实资源集合,即有一个等效的 WebRoleRefPermission 映射到它们的 Principal;因此,Policy::implies 将始终授予访问权限。但是手工制作的提供者,如自定义 SAM,可以从其他地方检索该知识,这样 @RolesAllowed 和委托给它的朋友仍然可以工作。毕竟它不像 Java EE 安全模型——包括填充 Subjects 的 "plumbing",将它们绑定到请求线程的 AccessControlContexts,处理 Subject::doAs(Privileged) 调用等等——变得无关紧要,只有提供者如何获得约束。当然,您的要求是否值得麻烦的问题仍然存在。