在研究servlet中的安全约束和过滤器时,我在web.xml文件中进行了以下声明,但没有像我预期的那样工作:
<security-constraint>
<web-resource-collection>
<web-resource-name>BeerSelector</web-resource-name>
<url-pattern>/SelectBeer.do</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>Admin</role-name>
</auth-constraint>
</security-constraint>
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>model.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/SelectBeer.do</url-pattern>
</filter-mapping>
根据我所读到的:过滤器应该在请求到达某个url之前遇到,那么,为什么首先调用安全约束呢?
我知道从安全角度来看这是有意义的(要到达必须进行身份验证的过滤器),但我想知道请求触发的序列。
容器是否首先搜索安全资源,从而触发安全约束?
但这将与Head First Servlets和Jsp""中引用的以下段落相矛盾
请记住,在DD中在请求之后发生。换句话说,客户已经当容器开始查看元素来决定如何响应。请求数据已经通过有线发送
或者请求只是触发了过滤器和安全约束,但安全约束比过滤器更受欢迎?
容器首先处理安全约束。
简而言之,Servlet容器首先检查传入的URL,并检查它是否符合所谓的排除或未检查约束。排除意味着任何人都不能访问该URL,而未检查意味着相反,允许所有人访问该URL。
在这个阶段,如果安装了所谓的JACC提供程序,容器可以调用自己的代码。
在此之后,容器可能会尝试对当前用户进行身份验证,在那里它可以再次调用您自己的代码。如果您注册了SAM(ServerAuthModule),则此时将始终调用它,如果您没有注册SAM,或者当您使用非完整的Java EE实现(例如,像TomEE这样的Java EE web配置文件服务器或像Tomcat这样的裸Servlet容器)时,这取决于服务器是否总是调用某种特定于服务器的登录模块(罕见),或者仅在未授权未经身份验证的用户访问时调用(典型)。
SAM是一个类似过滤器的东西,因为它可以重定向、转发和包装请求和响应,但它不是HTTP Servlet过滤器。
身份验证成功后,您的JACC策略将被再次调用,或者当您还没有安装JACC策略时,容器将使用专有机制来查看您在身份验证时是否有访问权限。
如果确实确定您有访问权限,那么将调用所谓的"资源",这意味着容器将调用过滤链中的第一个Filter,它最终将调用所请求的URL映射到的目标Servlet。
您可以在此处阅读有关SAM的更多信息:http://arjan-tijms.omnifaces.org/2012/11/implementing-container-authentication.html
点击此处了解更多关于JACC提供商的信息:http://arjan-tijms.omnifaces.org/2014/03/implementing-container-authorization-in.html
Filter执行进入请求的"服务"端。在此之前存在安全约束。它们帮助服务器决定是否提供url。您可以将过滤器的角色看作是"在servlet执行之前/之后"执行的东西。