刚刚接触Struts Menu的时候,对Struts Menu基于角色的菜单显示很好理解,但是如何将web应用中的角色管理映射到Struts Menu中,是困扰笔者良久的问题。经过摸索,在查阅了Tomcat的手册之后,笔者找到了答案。
Servlet容器和web应用都可以控制web应用资源的安全,因此Tomcat管理域有容器管理和应用程序管理两种,默认使用容器管理。通常web应用中使用的登陆Servlet和JSP则是应用程序管理。这就涉及到Realm的概念。
Tomcat在%CATALINA_HOME%/conf/server.xml文件中配置Realm,结合在%CATALINA_HOME%/WEB-INF/mywebapp/web.xml文件中配置的<security-constraint>,定义了存储用户和角色的信息,以及进行用户验证的方式。
Tomcat中定义的Realm有如下几种实现:UserDatabaseRealm、JDBCRealm、JNDIRealm和JAASRealm。下载Tomcat解压缩后默认使用的是UserDatabaseRealm。该Realm从%CATALINA_HOME%/conf/tomcat-users.xml静态文件中加载内存,Tomcat运行期间不会动态加载。因此所有的用户、角色和密码都是在Tomcat启动之前配置好的,只存在于内存中。修改tomcat-users.xml文件后必须重新启动Tomcat,该文件的具体配置请参考Tomcat手册。
本文要着重介绍的是JDBCRealm,该Realm使用关系数据库,能够动态访问数据。用户、角色和密码都保存在数据库中,一旦数据库有变化,JDBCRealm会立即访问。相应,JDBCRealm的设置需要数据库的访问参数。Tomcat5.0.28中给出了几种数据库的配置参数,示例如下:
<Realm className="org.apache.catalina.realm.JDBCRealm"
debug="99" digest="MD5"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@ntserver:1521:ORCL"
connectionName="scott" connectionPassword="tiger"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />
属性说明如下:
className是实现Realm的类名,对于JDBCRealm必须是org.apache.catalina.realm.JDBCRealm。
debug设置调试信息的详细程度等级,0表示不调试,数字越大越详细。
digest是数据库中密码字段的加密摘要算法名称,有SHA、MD2或MD5,默认是cleartext,即不加密。
driverName是数据库访问的JDBC驱动
connectionURL是数据库访问URL参数
connectionName和connectionPassword是访问数据库的名称和密码
userTable是web应用中存储用户信息的表名
userNameCol是用户信息表中存储用户登陆名称的字段名
userCredCol是用户信息表中存储用户登陆密码的字段名
userRoleTable是将用户角色映射表名
roleNameCol是角色表中存储角色名称的字段名
有了这些定义,web应用中定义的用户和角色就可以在Struts Menu中,用于配置基于角色可见与否的菜单。