自从我做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会"正常"触发,即仅当有人尝试访问需要身份验证的URI时,如<security-constraint>
所述。
可能值得注意的是,唯一起作用的 servlet 是使用@ApplicationPath("/v2")
注释 JAX-RSApplication
类时默认安装的 servlet。
SAM 确实完全负责身份验证。它可以遵循声明性配置,但不是必需的。它甚至可以完全自行执行 Servlet 请求的授权(尽管这样做远远超出了其合约的范围)。
根据JASPIC规范的§ 3.8.3,validateRequest
"在满足相应连接要求的每个请求上"在配置的ServerAuthContext
(因此在这种情况下也是其单个封装的SAM)上调用
。如果 SAM 想知道 Servlet 端点在描述符或注释方面是否应被视为"受保护",它可以在初始化时对中继给它的request
MessagePolicy
参数调用isMandatory
,或者在消息身份验证时探测MessageInfo
参数的映射是否存在"javax.security.auth.message.MessagePolicy.isMandatory"
键和等于Boolean.valueOf(value).booleanValue() == true
的映射值(规范 § 3.8.1.1)。
最后但并非最不重要的一点是,声明性安全约束在授权方面是否无关紧要?首先,我不确定各种规范是否可以分配未声明的角色的 SAM。除此之外,我从未尝试过这个,所以我只能猜测并提供一个模糊的答案。我对此的看法是,它或多或少与身份验证提供程序的情况相同。您实质上是将配置提供程序的责任从 AS 中移开,因此您必须以某种方式进行补偿,即提供备用配置接口。假设授权由某个 JACC 提供商管理。如果它是默认的,AS提供的,在没有声明性安全约束的情况下,它将无法承认调用者需要具有"emcc"
角色才能访问/v2/*
资源集合的事实,即具有映射到其Principal
的等效WebRoleRefPermission
;因此,Policy::implies
将始终授予访问权限。但是,手工制作的提供程序(如自定义SAM)可以从其他地方检索该知识,这样委派给它的@RolesAllowed
和朋友仍然可以工作。毕竟,Java EE安全模型——包括填充Subject
的"管道",将它们绑定到请求线程的AccessControlContext
,处理Subject::doAs(Privileged)
调用等等——并不是变得无关紧要,只有提供者如何获得约束才变得无关紧要。当然,您的要求是否证明麻烦的问题仍然存在。