Tôi đang sử dụng máy chủ GlassFish 4.0, trong đó tôi đã gán các quyền/vai trò khác nhau cho những người dùng khác nhau.Làm cách nào để mỗi người dùng truy cập tài nguyên tại một vị trí cụ thể theo quyền hạn/vai trò của họ trong JAAS?
Người dùng có thể có nhiều quyền/vai trò. Ví dụ: người dùng quản trị có thể được liên kết với ROLE_ADMIN
(để thực hiện các tác vụ quản trị) và ROLE_USER
(để thực hiện các tác vụ với tư cách người dùng đã đăng ký).
Trong số web.xml
, cấu hình này được định cấu hình như sau.
<security-constraint>
<display-name>AdminConstraint</display-name>
<web-resource-collection>
<web-resource-name>ROLE_ADMIN</web-resource-name>
<description/>
<url-pattern>/admin_side/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>ROLE_ADMIN</role-name>
</auth-constraint>
<user-data-constraint>
<description/>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-constraint>
<display-name>UserConstraint</display-name>
<web-resource-collection>
<web-resource-name>ROLE_USER</web-resource-name>
<description/>
<url-pattern>/user_side/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>ROLE_USER</role-name>
</auth-constraint>
<user-data-constraint>
<description/>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<!--<auth-method>DIGEST</auth-method>-->
<auth-method>FORM</auth-method>
<realm-name>projectRealm</realm-name>
<form-login-config>
<form-login-page>/utility/Login.jsf</form-login-page>
<form-error-page>/utility/ErrorPage.jsf</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description/>
<role-name>ROLE_ADMIN</role-name>
</security-role>
<security-role>
<description/>
<role-name>ROLE_USER</role-name>
</security-role>
Điều này chỉ hoạt động tốt.
Có hai mẫu URL /admin_side/*
và /user_side/*
. Quản trị viên có hai vai trò ROLE_ADMIN
và ROLE_USER
.
Khi quản trị viên đăng nhập bằng quyền hạn ROLE_USER
, chỉ cần truy cập chỉ tài nguyên ở số /user_side/*
. Tài nguyên nằm ở /admin_side/*
không được phép truy cập vì quản trị viên được đăng nhập với tư cách là người dùng đã đăng ký và không phải là quản trị viên.
Cho đến bây giờ điều xảy ra trong trường hợp của tôi là khi quản trị viên đăng nhập bằng bất kỳ cơ quan nào, tài nguyên ở cả hai vị trí đều có thể truy cập hoàn toàn bất hợp pháp. Đó là bởi vì hệ thống có thể định vị cả chính quyền cho người dùng cụ thể đó.
Làm cách nào để mỗi người dùng truy cập tài nguyên tại một vị trí cụ thể theo quyền hạn/vai trò của họ?
Bộ lọc xác thực:
@WebFilter(filterName = "SecurityCheck", urlPatterns = {"/jass/*"})
public final class SecurityCheck implements Filter
{
private FilterConfig filterConfig = null;
@Resource(mappedName="jms/destinationFactory")
private ConnectionFactory connectionFactory;
@Resource(mappedName="jms/destination")
private Queue queue;
@EJB
private final UserBeanLocal userService=null;
public SecurityCheck() {}
private void sendJMSMessageToDestination(String message) throws JMSException
{
Connection connection = null;
Session session = null;
try
{
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(queue);
TextMessage textMessage = session.createTextMessage();
textMessage.setText(message);
messageProducer.send(textMessage);
}
finally
{
if(session!=null){session.close();}
if(connection!=null){connection.close();}
}
}
private void doBeforeProcessing(ServletRequest request, ServletResponse response) throws IOException, ServletException
{
HttpServletRequest httpServletRequest=(HttpServletRequest)request;
httpServletRequest.login(httpServletRequest.getParameter("userName"), httpServletRequest.getParameter("password"));
}
private void doAfterProcessing(ServletRequest request, ServletResponse response) throws IOException, ServletException, JMSException
{
HttpServletRequest httpServletRequest=(HttpServletRequest)request;
HttpServletResponse httpServletResponse=(HttpServletResponse)response;
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
Map<String, Object> sessionMap = externalContext.getSessionMap();
if(httpServletRequest.isUserInRole("ROLE_USER"))
{
sendJMSMessageToDestination(httpServletRequest.getLocalName());
UserTable userTable = userService.setLastLogin(httpServletRequest.getParameter("userName"));
userTable.setPassword(null);
sessionMap.put("userName", userTable!=null?userTable.getFirstName():"Unknown");
sessionMap.put("user", userTable);
httpServletResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.sendRedirect("../user_side/Home.jsf");
}
else if(httpServletRequest.isUserInRole("ROLE_ADMIN"))
{
sendJMSMessageToDestination(httpServletRequest.getLocalName());
UserTable userTable = userService.setLastLogin(httpServletRequest.getParameter("userName"));
userTable.setPassword(null);
sessionMap.put("adminName", userTable!=null?userTable.getFirstName():"Unknown");
sessionMap.put("user", userTable);
httpServletResponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.sendRedirect("../admin_side/Home.jsf");
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
try
{
doBeforeProcessing(request, response);
}
catch (Exception e)
{
HttpServletResponse httpServletResponse=(HttpServletResponse)response;
//FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Incorrect user name and/or password. Access denied."));
httpServletResponse.sendRedirect("../utility/Login.jsf");
return;
}
chain.doFilter(request, response);
try
{
doAfterProcessing(request, response);
}
catch (JMSException ex)
{
Logger.getLogger(SecurityCheck.class.getName()).log(Level.SEVERE, null, ex);
}
}
//The rest of the filter.
}
Nếu bạn cần phải nhìn thấy những thứ khác trong ứng dụng của tôi sau đó, xin vui lòng cho tôi biết.
Bạn đăng nhập vào quản trị viên với tư cách người dùng đã đăng ký chính xác như thế nào? Nếu một người dùng cụ thể có nhiều vai trò, thì thực sự không có cách nào để đăng nhập chỉ bằng một trong những vai trò đó. Vì vậy, toàn bộ câu hỏi là khó hiểu. – BalusC
Đây là bộ lọc xác thực người dùng. Bộ lọc được ánh xạ tới URL patter - '/ jass/*' (đã nhập nhầm, phải là '/ jaas/*'). Nó chỉ ra một thư mục trong đó chỉ có một trang - 'temp.jsp', nơi yêu cầu được gửi đi, khi nhấn nút đăng nhập trên trang JSF (thông qua đậu được quản lý JSF tương ứng của nó). Không có cách nào để đăng nhập một lần với tư cách quản trị viên và một lần với tư cách là người dùng sử dụng cùng một id/mật khẩu? Tôi cũng cảm thấy như vậy nhưng nghĩ rằng các container có thể hỗ trợ một số cơ chế để làm điều này. Tôi nhìn vào một số hướng dẫn nhưng không tìm thấy gì về nó. – Tiny