使用声明式安全(即通过 web.xml)这是不可能的。您只能列出有权访问资源的角色,如下所示:
<security-constraint>
<web-resource-collection>
<web-resource-name>auth</web-resource-name>
<url-pattern>/doc/profesionalCustomer.pdf</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>professional</role-name>
<role-name>customer</role-name>
</auth-constraint>
但是,在这种情况下,您将向所有具有专业或客户角色的用户授予访问权限,这不是您想要的。没有允许您为具有角色组合的用户授予访问权限的结构。
您可以采取的一种方法是以编程方式处理它:将客户端引导到一个 servlet,该 servlet 检查用户是否同时处于客户和专业角色中HttpServletRequest#isUserInRole(String)
,如果它将请求转发到检索 pdf 的默认 servlet。此外,如果您想推迟授予哪些角色组合访问部署时间,而不是将其硬编码在 servlet 中,您可以通过web.xml 的/web-app/servlet/init-param
or/web-app/context-param
元素适当地参数化授予 servlet。
以下是支持这一点的 web.xml 摘录:
<servlet>
<servlet-name>PDF Retriever</servlet-name>
<servlet-class>com.stackoverflow.PDFRetrieverServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PDF Retriever</servlet-name>
<url-pattern>/docs/pdf/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>PDF Docs - customer and professional only</web-resource-name>
<url-pattern>/docs/pdf/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>PDF Docs Private</web-resource-name>
<url-pattern>/private/pdf/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name />
</auth-constraint>
</security-constraint>`
这是 servlet 的 doGet 的编码:
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
if (request.isUserInRole("customer") && request.isUserInRole("professional")) {
String urlSuffix = request.getPathInfo();
RequestDispatcher rd = request.getRequestDispatcher("/private/pdf"
+ urlSuffix);
rd.forward(request, response);
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
}