这是不可能使用声明安全(即经由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)
来检查用户是否具有客户和专业角色,并且它将请求转发给默认servlet检索pdf。此外,如果您想推迟什么组合角色被授予访问部署时间的权限,而不是在servlet中对其进行硬编码,则可以通过您的web.xml的/web-app/servlet/init-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);
}
}
谢谢你的回答。 我唯一担心的是,如果有人知道PDF文件的完整路径,他可以直接访问它,而无需任何控制。 – Pierpaolo
@Pierpaolo我编辑了包含web.xml和servlet代码的答案。为了防止每个人访问PDF,您可以将URL放置在一个没有角色可以访问的保护区中(您的pdf文件实际位于/ private/pdf目录下) - 请注意第二个空角色名称元素安全性约束。唯一的访问是通过PDFRetrievalServlet。 – Nenad