使用Java 验证和授权服务(JAAS)可以很好地解决上面的问题,你可以用它来管理应用程序的安全性。JAAS具有两个特性:验证(Authentication)和授权(authorization),认证是完成用户名和密码的匹配校验;授权是决定用户可以访问哪些资源,授权是基于角色的。Jboss 服务器提供了安全服务来进行用户认证和根据用户规则来限制对POJO 的访问。对每一个POJO 来说,你可以通过使用@SecurityDomain 注释为它指定一个安全域, 安全域告诉容器到哪里去找密码和用户角色列表。JBoss 中的other 域表明文件是classpath 中的users.propertes 和roles.properties。这样,对每一个方法来说,我们可以使用一个安全限制注释来指定谁可以运行这个方法。比如,下面的例子,容器对所有试图调用AdminUserMethod()的用户进行认证,只允许拥有AdminUser 角色的用户运行它。如果你没有登录或者没有以管理员的身份登录,一个安全意外将会抛出。
本例使用了Jboss 默认的安全域”other”, “other”安全域告诉容器到classpath 中的users.propertes 和roles.properties
找密码和用户角色列表。”other”安全域的定义在[jboss 安装目录]/server/default/conf/login-config.xml 文件。内容如
下:
@PermitAll 注释定义的资源,可以修改”other”安全域配置,修改片断如下(蓝色部分):
找密码和用户角色列表。”other”安全域的定义在[jboss 安装目录]/server/default/conf/login-config.xml 文件。内容如
下:
<application-policy name = "other"> <!--A simple server login module, which can be used when the number of users is relatively small. It uses two properties files: users.properties, which holds users (key) and their password (value). roles.properties, which holds users (key) and a comma-separated list of their roles (value). The unauthenticatedIdentity property defines the name of the principal that will be used when a null username and password are presented as is the case for an unuathenticated web client or MDB. If you want to allow such users to be authenticated add the property, e.g., unauthenticatedIdentity="nobody" --> <authentication> <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule" flag = "required" /> </authentication> </application-policy>“other”安全域默认情况下是不允许匿名用户(不提供用户名及密码)访问的,如果你想使匿名用户也可访问通过
@PermitAll 注释定义的资源,可以修改”other”安全域配置,修改片断如下(蓝色部分):
<application-policy name = "other"> <authentication> <login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule" flag = "required" /> <module-option name = "unauthenticatedIdentity">AnonymousUser</module-option> </authentication> </application-policy>安全服务的具体开发:
开发的第一步是定义安全域,安全域的定义有两种方法:
第一种方法:通过Jboss 发布文件(jboss.xml)进行定义(本例采用的方法),定义内容如下:
jboss.xml(本例使用Jboss 默认的安全域”other”)
<?xml version="1.0" encoding="UTF-8"?> <jboss> <!-- Bug in EJB3 of JBoss 4.0.4 GA <security-domain>java:/jaas/other</security-domain>--> <security-domain>other</security-domain> <unauthenticated-principal>AnonymousUser</unauthenticated-principal> </jboss>定义好安全域之后,因为我们使用Jboss 默认的安全域”other”,所以必须使用users.propertes 和roles.properties 存
储用户名/密码及用户角色。
开发的第二步就是定义用户名,密码及用户的角色。用户名和密码定义在users.propertes 文件,用户所属角
色定义在roles.properties 文件。以下是这两个文件的具体配置:
users.propertes(定义了本例使用的三个用户)
lihuoming=123456
zhangfeng=111111
wuxiao=123
roles.properties(定义了三个用户所具有的角色,其中用户lihuoming 具有三种角色)
lihuoming=AdminUser,DepartmentUser,CooperateUser
zhangfeng=DepartmentUser
wuxiao=CooperateUser
lihuoming=AdminUser,DepartmentUser,CooperateUser
zhangfeng=DepartmentUser
wuxiao=CooperateUser
以上两个文件必须存放于类路径下。在进行用户验证时,Jboss 容器会自动寻找这两个文件
开发的第三步就是为业务方法定义访问角色。本例定义了三个方法:AdminUserMethod(),DepartmentUserMethod(),AnonymousUserMethod(),第一个方法只允许具有AdminUser 角色的用户访问,第二个方法只允许具有DepartmentUser 角色的用户访问,第三个方法允许所有角色的用户访问。下面是Session
Bean 代码。
SecurityAccessBean.java
SecurityAccessBean.java
import javax.ejb.Remote; import javax.ejb.Stateless; @Stateless @Remote ({SecurityAccess.class}) public class SecurityAccessBean implements SecurityAccess{ @RolesAllowed({"AdminUser"}) public String AdminUserMethod() { return "具有管理员角色的用户才可以访问AdminUserMethod()方法"; } @RolesAllowed({"DepartmentUser"}) public String DepartmentUserMethod() { return "具有事业部门角色的用户才可以访问DepartmentUserMethod()方法"; } @PermitAll public String AnonymousUserMethod() { return "任何角色的用户都可以访问AnonymousUserMethod()方法, 注:用户必须存在 users.properties文件哦"; } } @RolesAllowed 注释定义允许访问方法的角色列表,如角色为多个,可以用逗号分隔。@PermitAll 注释定义所有 的角色都可以访问此方法。
<%@ page contentType="text/html; charset=GBK"%> <%@ page import="com.foshanshop.ejb3.SecurityAccess, javax.naming.*, java.util.*"%> <% Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory"); props.setProperty(Context.PROVIDER_URL, "localhost:1099"); props.setProperty(Context.SECURITY_PRINCIPAL, ""); props.setProperty(Context.SECURITY_CREDENTIALS, ""); String user = request.getParameter("user"); String pwd = request.getParameter("pwd"); if (user!=null && !"".equals(user.trim())){ props.setProperty(Context.SECURITY_PRINCIPAL, user); props.setProperty(Context.SECURITY_CREDENTIALS, pwd); } InitialContext ctx = new InitialContext(props); SecurityAccess securityaccess = (SecurityAccess) ctx.lookup("SecurityAccessBean/remote"); try{ out.println("<font color=green>调用结果:</font>"+ securityaccess.AdminUserMethod()+ "<br>"); }catch(Exception e){ out.println(user+ "没有权限访问AdminUserMethod方法<BR>"); } out.println("==========================<BR>"); try{ out.println("<font color=green>调用结果:</font>"+ securityaccess.DepartmentUserMethod()+ "<br>"); }catch(Exception e){ out.println(user+ "没有权限访问DepartmentUserMethod方法<BR>"); } out.println("==========================<BR>"); try{ out.println("<font color=green>调用结果:</font>"+ securityaccess.AnonymousUserMethod()+ "<br>"); }catch(Exception e){ out.println(user+ "没有权限访问AnonymousUserMethod方法<BR>"); } %>
<html> <head> <title>安全访问测试</title> </head> <body> <center><h2>安全访问测试</h2></center> <br /> 请输入你的用户名及密码 <br /> <form method="POST" action="SecurityAccessTest.jsp"> Username: <input type="text" name="user"/> <br /> Password: <input type="password" name="pwd"/> <br /> <input type="submit" value="身份验证"/> </form> <p> 管理员 用户名: <STRONG>lihuoming</STRONG> 密码: <STRONG>123456</STRONG> </p> <p>事业部 用户名: <STRONG>zhangfeng</STRONG> 密码 <STRONG>111111</STRONG></p> <p>合作伙伴 用户名: <STRONG>wuxiao</STRONG> 密码 <STRONG>123</STRONG></p> </body> </html>