使用jdonframework+jboss配置基于jaas的url验证

学习jdonframework和jaas,自己配置的权限控制,共享下

1、建立struts访问页面
login.jsp 登录页面,填写用户名和密码登录
//login.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib uri="struts-html" prefix="html" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%-- 此处的/login为jdonframework提供的servelet com.jdon.security.web.LoginServlet --%>
<form action="<%=request.getContextPath()%>/login" method="post">

<table>
<tr>
<td>用户名</td>
<td><input type="text" id="username" name="j_username"></td>
</tr>
<tr>
<td>密码</td>
<td><input type="text" id="password" name="j_password"></input></td>
</tr><tr>
<td colspan="2"><input type="submit" id="login" name="login" value="login"></input></td>
</tr></table>
</form>
</body>
</html>
页面的用户名和密码输入框名称必须为j_username和j_password,这是jaas的约定

在web.xml配置login.jsp页面的servlet
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>

login_error.jsp 登录验证错误返回页面,提示登录验证失败信息
result.jsp 不使权限保护的测试页面
platmanager/pagelist.jsp 通过目录palamanager保护的页面

除了login.jsp页面需要设置输入标签和登录按钮外,其他的测试页面只需要显示文本区别即可
2、配置login.jsp页面使用的servlet
<servlet>
<servlet-name>jaaslogin</servlet-name>
<servlet-class>
com.jdon.security.web.LoginServlet
</servlet-class>
<init-param>
<param-name>login</param-name>
<param-value>/login.jsp</param-value>
</init-param>
</servlet>
配置servlet的url映射为/login
<servlet-mapping>
<servlet-name>jaaslogin</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<welcome-file-list>
3、在web.xml配置角色和权限

以下是定义url资源/platmanager/* 需要Admin权限访问
<security-constraint>
<web-resource-collection>
<web-resource-name>admin need</web-resource-name>
<url-pattern>/platmanager/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Admin</role-name>
</auth-constraint>
</security-constraint>

配置验证方式、验证页面和失败返回的页面
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/login_error.jsp</form-error-page>
</form-login-config>
</login-config>

定义系统的角色,当前为Admin和User
<security-role>
<role-name>User</role-name>
</security-role>
<security-role>
<role-name>Admin</role-name>
</security-role>
角色定义的名称必须和数据库或验证文件里的角色名称对应,注意区分大小写
以上的三个部分在web.xml里配置时必须按照当前的顺序,否则会提示错误,如果缺少该配置,系统运行过程中会发生找不到servlet的错误
4、配置jboss-web.xml
新建文件jboss-web.xml,增加jboss权限域
<jboss-web>
<security-domain>java:/jaas/SecurityRealm</security-domain>
</jboss-web>
5、配置jboss域
jboss目录server\default\conf下的login-config.xml文件是jboss服务器提供的域权限配置文件,该文件可以对不同的域配置不同的权限体系
可以配置基于文件系统的权限系统,也可以配置基于数据库的权限系统,如果是基于文件系统的权限体系可以参考文件里其他域的权限配置,可以指定文件配置用户和权限信息,我们这里设置基于mysql数据库的权限系统,相关配置如下
<application-policy name = "SecurityRealm">
<authentication>
<login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required">
<module-option name = "dsJndiName">java:/Security</module-option>
<module-option name="principalsQuery">SELECT password AS Password FROM user WHERE name = ?</module-option>
<module-option name="rolesQuery">SELECT RL.name AS Roles, 'Roles' AS RoleGroups FROM role as RL, user as U , users_roles as RU WHERE U.userid = RU.userid and RU.roleid = RL.roleid and U.name = ?</module-option>
<module-option name="debug">true</module-option>
<module-option name="hashAlgorithm">MD5</module-option>
<module-option name="hashEncoding">hex</module-option>
</login-module>
</authentication>
</application-policy>

其中java:/Security是jboss访问数据库的jndi名称,需要在jboss中配置,以便jboss可以访问我们的数据库,新建文件mysql-ds.xml,配置如下代码

<datasources>
<xa-datasource>
<jndi-name>Security</jndi-name>
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
<xa-datasource-property name="URL">jdbc:mysql://127.0.0.1:3306/security?useUnicode=true&characterEncoding=utf8&characterResultSets=utf8</xa-datasource-property>
<user-name>test</user-name>
<password>test</password>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<track-connection-by-tx>true</track-connection-by-tx>
<new-connection-sql>set autocommit=1</new-connection-sql>
<no-tx-separate-pools>true</no-tx-separate-pools>

</xa-datasource>
</datasources>
主要是修改数据库连接和数据库的用户名和密码

域设置中的principalsQuery是用户的访问语句,rolesQuery是基于角色的权限查询语句,可获得具体用户的角色
一下是数据库的创建脚本,如果安装了jivejdon,则可以使用它的security数据库
CREATE TABLE user (
userId char(50) binary NOT NULL default '',
password char(50) binary default NULL,
name char(50) default NULL,
email char(50) default NULL,
PRIMARY KEY (userId),
UNIQUE KEY email (email),
UNIQUE KEY name (name),
KEY name_2 (name),
KEY email_2 (email)
) TYPE=InnoDB;

CREATE TABLE role (
roleId char(50) binary NOT NULL default '',
name char(100) default NULL,
PRIMARY KEY (roleId)
) TYPE=InnoDB;


CREATE TABLE users_roles (
userId char(50) NOT NULL default '',
roleId char(50) NOT NULL default '',
KEY userId (userId)
) TYPE=InnoDB;

CREATE TABLE passwordassit (
userId char(50) NOT NULL default '',
passwdtype varchar(100) default NULL,
passwdanswer varchar(100) default NULL,
PRIMARY KEY (userid),
KEY passwdtype (passwdtype)
) TYPE=InnoDB;


INSERT INTO `user` ( `userId` , `name` , `password` , `email` ) VALUES ('1', 'admin', '21232f297a57a5a743894a0e4a801fc3', 'admin@yoursite.com');
INSERT INTO `role` ( `roleId` , `name` ) VALUES ('2', 'Admin');
INSERT INTO users_roles VALUES ('1', '2');
6、部署运行
至此,我们将程序打包部署到jboss
运行result.jsp页面,会进入该页面
运行页面platmanager/pagelist.jsp,会转到登录页面要求输入用户名密码,输入用户名admin,密码admin,点击login按钮,会进入pagelist页面,说明验证成功
[该贴被yxh1122于2010-05-06 18:17修改过]
[该贴被yxh1122于2010-05-06 18:18修改过]

2010年05月06日 18:14 "yxh1122"的内容
在web.xml配置角色和权限

以下是定义url资源/platmanager/* 需要Admin权限访问


<web-resource-na ...

能否将url的权限访问放到到数据库里呢?我感觉那样会更灵活
再自己定义个javax.servlet.Filter来检查权限。

或者jaas是否直接支持将页面权限配置放到数据库里面?

或者角色不是从直接从数据库取值,而是访问某个服务如何配置呢?
因为角色获取未必一个sql语句就够,也许有更复杂的逻辑?

我的一些想法,望指点迷津,谢谢

2010年05月07日 08:13 "iliuyong"的内容
因为角色获取未必一个sql语句就够,也许有更复杂的逻辑 ...

如果自己定义javax.servlet.Filter来过滤用户访问,这个问题就好解决了

jaas只是做了对用户和角色的关联实现,对于具体的数据权限访问,也就是基于model的权限控制,这个属于特殊的权限验证,每个应用都会不同,因此无法做成统一标准,需要编写代码实现

其实角色的作用就是在用户和资源之间建立起的桥梁,用户和角色的关系是明确的,就是某个用户具有哪些角色,对于用户验证来讲就是获取该用户具有哪些角色,最多增加个角色组的概念,sql语句没有那么复杂,一般的应用足够了。

个人感觉,只要实现了基于页面资源的model权限控制,每个页面可以设置编辑查看等不同的操作,就可以满足系统权限的要求了。当然如果需要对其他具体的数据行实行权限验证,则需要进行单独的控制,这里的介绍只是针对jaas的初学应用,是否有url权限验证,这个需要具体情况考虑,如果将url验证放到数据库里当然也可以,不过做的工作就多了,既然jaas提供了支持,不妨用一下

jaas URL验证实际就是基于Web或JavaEE服务器的权限验证,缺点是每个服务器配置不统一,JEE标准对这部分没有规定,导致各个服务器不一样实现,Spring则是提供ACEGI专门的框架来实现,也需要配置,还需要AOP知识,至于哪个好,就仁者见仁,智者见智吧。

这里我补充一下tomcat下的jaas URL验证配置过程,来自jivejdon的doc/install_cn.txt文档,基本流程和楼主的Jboss配置差不多,不同就是和JBoss有关配置不一样:

(1)在Tomcat启动配置中加入授权JAAS配置。分windows catalina.bat和linux catalina.sh两个启动文件修改。

在tomcat/bin/catalina.bat找到如下字符串:
set JAVA_OPTS=%JAVA_OPTS%
在其后面以后加入 -Djava.security.auth.login.config=%CATALINA_BASE%/conf/jaas.config
整句应该如下:
set JAVA_OPTS =%JAVA_OPTS% -Djava.security.auth.login.config=%CATALINA_BASE%/conf/jaas.config

linux下的catalina.sh在找到如下字符串:
JAVA_OPTS="$JAVA_OPTS
在其后面以后加入-Djava.security.auth.login.config=$CATALINA_BASE/conf/jaas.config
整句应该如下,注意双引号:
JAVA_OPTS="$JAVA_OPTS -Djava.security.auth.login.config=$CATALINA_BASE/conf/jaas.config"

注意:这一步骤很关键,如果发现多个,就多个加入,宁可多勿少。
如果有报错:Cannot find message associated with key jaasRealm.unexpectedError
java.lang.SecurityException: 无法定位登录配置
大部分原因在此没有正确配置。

为确保无误,可以搜寻"--- Execute The Requested Command ------------"
catalina.bat中再加入:set JAVA_OPTS =%JAVA_OPTS% -Djava.security.auth.login.config=%CATALINA_BASE%/conf/jaas.config
catalina.sh中再加入:JAVA_OPTS="$JAVA_OPTS -Djava.security.auth.login.config=$CATALINA_BASE/conf/jaas.config"

(2)这一步和JAAS无关:下载http://www.jdon.com/jdonframework/download/jdonlib.rar
解压jdonlib/lib/*.jar所有jar,拷贝到tomcat/lib目录下

(3)在conf/server.xml的Host之前加入:

<Realm
className="org.apache.catalina.realm.JAASRealm"
appName="JiveJdonRealm"
userClassNames="com.jdon.jivejdon.auth.jaas.User"
roleClassNames="com.jdon.jivejdon.auth.jaas.Role"/>

<!-- Define the default virtual host
Note: XML Schema validation will not work with Xerces 2.2.
-->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">

(4) 本步骤是配置tomcat对输入用户名和密码读取哪个数据表进行验证,配置数据源。在conf/context.xml中配置数据源Datasource:
<Resource name="jdbc/JiveJdonDS"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="root"
password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/jivejdon?useUnicode=true&characterEncoding=UTF-8" />

<Resource name="jdbc/SecurityDS"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="root"
password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/jivejdon?useUnicode=true&characterEncoding=UTF-8" />

注意数据库的用户名和密码

(5)把doc/tomcat/conf/jaas.config拷贝到tomcat的conf目录下
确保jivejdon.war的WEB-INF/classes目录下存在jaas.properties
JAAS_DATASOURCE=java:comp/env/jdbc/JiveJdonDS

数据源jdbc/JiveJdonDS名称和第4步配置是一致的,前缀java:comp/env是JavaEE标准规定通用前缀
本步骤是配置tomcat对输入用户名和密码读取哪个数据表进行验证

(6)把doc/tomcat/lib下的jaas.jar拷贝到tomcat的lib目录下,专门为tomcat开发的有关用户名和密码如何认证的代码,感谢oojdon。

(7)启动startup.bat
使用http://localhost:8080/jivejdon/ 访问,注意不能是127.0.0.1 ,因为在tomcat中配置jaas的是localhost,不是127.0.0.1,否则权限出错。

我加上了,set JAVA_OPTS==%JAVA_OPTS% -Djava.security.auth.login.config="%CATALINA_BASE%/conf/jaas.config" 但是不管用 ,谁能帮我看看不 我的qq574620971 谢谢了

找啊找 还是让我给找到了,解决了,谢谢