我已经用Glassfish 3.1+JDBCRealm+MySQL(MD5)实现了基于FORM的身份验证。我只有两个角色,用户和管理员。一切都很顺利,我可以从日志中看到,身份验证在两种情况下都是有用的和管理员的(查看下面的日志)
Q1:是否可以制作两个不同的索引文件,以便当用户是管理员时,他/她转到/admin/index.xhtml,而当用户是角色用户时,他直接转到faces/user/index.xhtml?
Q2:现在,当我以用户身份登录时,我仍然可以转到"管理端",只需在浏览器中直接将整个链接写入地址字段,为什么要避免这种情况?
Q3:当我以用户身份登录,并且我在欢迎文件列表中只有faces/admin/index.xhtml时,即使xml文件告诉其他内容,它也会将我重定向到该文件,为什么?
<welcome-file-list>
<welcome-file>faces/admin/index.xhtml</welcome-file> *?? ----> it goes always here, cause it is the first one I think?*
<welcome-file>faces/user/index.xhtml</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>Admin Pages</display-name>
<web-resource-collection>
<web-resource-name>Protected Admin Area</web-resource-name>
<description/>
<url-pattern>/faces/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>User Pages</display-name>
<web-resource-collection>
<web-resource-name>Protected Users Area</web-resource-name>
<description/>
<url-pattern>/faces/users/*</url-pattern>
<!--url-pattern>/faces/users/index.xhtml</url-pattern-->
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>HEAD</http-method>
<http-method>PUT</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>JDBCRealm</realm-name>
<form-login-config>
<form-login-page>/faces/loginForm.xhtml</form-login-page>
<form-error-page>/faces/loginError.xhtml</form-error-page>
</form-login-config>
</login-config>
</web-app>
日志:
FINE: Login module initialized: class com.sun.enterprise.security.auth.login.JDBCLoginModule
FINEST: JDBC login succeeded for: admin groups:[admin, user]
FINE: JAAS login complete.
FINE: JAAS authentication committed.
FINE: Password login succeeded for : admin
FINE: Set security context as user: admin
FINE: [Web-Security] Setting Policy Context ID: old = null ctxID = jdbcrealm/jdbcrealm
FINE: [Web-Security] hasUserDataPermission perm: (javax.security.jacc.WebUserDataPermission GET)
FINE: [Web-Security] hasUserDataPermission isGranted: true
FINE: [Web-Security] Policy Context ID was: jdbcrealm/jdbcrealm
FINE: [Web-Security] Codesource with Web URL: file:/jdbcrealm/jdbcrealm
FINE: [Web-Security] Checking Web Permission with Principals : null
(根据myfear的回答进行编辑)-----在glassfish-web.xml我有这样的角色。如果我理解正确,这意味着管理员属于组:管理员、客户和用户。客户属于组:客户和用户,用户属于组用户。我理解对了吗?
<security-role-mapping>
<role-name>admin</role-name>
<group-name>admin</group-name>
<group-name>customer</group-name>
<group-name>user</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>customer</role-name>
<group-name>customer</group-name>
<group-name>user</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>user</role-name>
<group-name>user</group-name>
</security-role-mapping>
</glassfish-web-app>
谢谢!萨米语
我刚刚在大学课堂上尝试过这一点,下面是我如何获得我认为您正在追求的功能。我将Netbeans与Glassfish 4.1.1服务器一起使用,并且已经在服务器文件领域中配置了用户角色。
我的项目有3个文件:
index.xhtml
users/mainmenu.xhtml
admin/mainmenu.xhtml
欢迎页面设置为index.xhtml
,并具有以下超链接:
<h4>
<a href="/ED-Secure-war/faces/admin/mainmenu.xhtml">
Admin Login
</a>
</h4>
<h4>
<a href="/ED-Secure-war/faces/user/mainmenu.xhtml">
User Login
</a>
</h4>
在我的web.xml安全部分中,我配置了以下角色
现在,由于对每个超链接的访问都受到用户组的限制,当您单击索引上的超链接时,系统会提示您登录。如果您为管理员链接输入了有效的管理员登录名,您将被重定向到admin/mainmenu.xhtml
,反之亦然。
A1)欢迎文件与角色无关。如果你需要为调度用户做任何类型的逻辑,你需要考虑使用布尔型HttpServletRequest.isUserInRole(字符串角色)或类似的东西来找出用户的角色。
A2)那不应该发生。您需要检查您在JDBCRealm中的角色。在我看来,一切都是以正确的方式配置的。
A3)我不确定我是否正确理解你的备注"XML"文件。但是欢迎文件不绑定到角色和。。参见A1)
谢谢,M
对于您的问题1:使用过滤器,您可以将用户重定向到特定页面userlogin.xhtml或adminlogin.xhtml
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String userName = SecurityAssociation.getPrincipal().getName();
String userNameSubject = SecurityAssociation.getSubject().toString();
System.out.println("Yeeey! Get me here and find me in the database: " + userName+ " Subject : "+userNameSubject);
filterChain.doFilter(servletRequest, servletResponse);
}