赞
踩
实现安全验证事务有两种方式:
安全域是Web服务器用来保护Web应用的资源的一种机制。在安全域中可以配置安全验证信息,其用户信息(包括用户名和口令)以及用户和角色的映射关系。每个用户可以拥有一个或多个角色,每个角色限定了可访问的Web资源。
安全域是Tomcat内置的功能,在org.apache.catalina.Realm接口中声明了把一组用户名、口令以及所关联的角色集成到Tomcat中的方法。Tomcat为 Realm接口提供了一些实现类。下表列出了常见的一些 Realm实现类,它们代表不同的安全域类型。
安全域类型 | 类名 | 描述 |
---|---|---|
内存域 | MemoryRealm | 在初始化阶段,从XML文件中读取安全验证信息,并把他们以一组对象的形式存放在内存中。 |
JDBC域 | JDBCRealm | 通过JDBC驱动程序访问存放在数据库中的安全验证信息。 |
数据源域 | DataSourceRealm | 通过JNDI数据源访问存放在数据库中的安全验证信息。 |
JNDI域 | JNDIRealm | 通过JNDI provider访问存放在基于LDAP的目录服务器中的安全验证信息。 |
JAAS域 | JAASRealm | 利用JAAS(Java验证与授权服务)框架进行验证。 |
合并域 | CombinedRealm | 合并使用其他的安全域,从多种来源(例如XML文件或数据库)中获取安全验证信息。 |
不管配置哪一种类型的安全域,都包含以下步骤
在Web应用的 WEB-INF/web.xml 文件中为 Web资源设置安全约束。
在Tomcat的<CATALINA_HOME>/conf/server.xml配置文件中,或者 Web应用的META-INF/context.xml文件中配置<Realm>元素,形式如下:
<Realm className="...实现这一安全域的类的名字" ...其它属性... />
元素在 server.xml中的嵌入位置见下表:
嵌入位置 | 描述 |
---|---|
<Engine>中 | <Engine>中所有虚拟主机上的所有 Web应用共享这个 Realm。例外情况是在这个<Engine>下的<Host> 或<Context>元素下还定义了自己的 Realm元素 |
<Host>中 | <Host>下的所有 Web应用共享这个 Realm。例外情况是在这个<Host>下的<Context>元素下还定义了自己的 Realm元素 |
<Context>中 | 只有<Context>元素对应的Web应用才能使用这个Realm |
为Web资源设置安全约束,需要在Web应用的web.xml文件中加入<security-constraint>、<login-config>和<security-role>元素。
在<security-constraint>元素中指定受保护的 Web资源以及所有可以访问该 Web资源的角色。例如在Tomcat的<CATALINA_HOME>/webapps/webapps/manager应用中声明了如下安全约束:
<security-constraint>
<web-resource-collection>
<web-resource-name>Text Manager interface (for scripts)</web-resource-name>
<url-pattern>/text/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager-script</role-name>
</auth-constraint>
</security-constraint>
以上安全约束代码指明:manager-script角色能访问 manager应用中URL入口为 “/text/*” 资源。
例如在Tomcat的<CATALINA_HOME>/webapps/webapps/examples应用中声明了如下安全约束:
<security-constraint> <display-name>Example Security Constraint - part 1</display-name> <web-resource-collection> <web-resource-name>Protected Area - Allow methods</web-resource-name> <url-pattern>/jsp/security/protected/*</url-pattern> <http-method>DELETE</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <auth-constraint> <role-name>tomcat</role-name> <role-name>role1</role-name> </auth-constraint> </security-constraint>
以上安全约束代码指明:只有 tomcat和role1角色能以DELETE、GET、POST或PUT方式访问examples应用中URL入口为 “/jsp/security/protected/”下的Web资源。
<security-constraint>元素的各个子元素的说明见下表:
属性 | 说明 |
---|---|
<web-resource-collection> | 声明受保护的Web资源 |
<web-resource-name> | 标识受保护的Web资源 |
<url-pattern> | 指定受保护的URL路径 |
<http-method> | 指明受保护的HTTP请求方式 |
<auth-constraint> | 声明可以访问受保护资源的角色 |
<role-name> | 指明可以访问受保护资源的角色 |
在web.xml文件中再加入<login-config>元素,它指定当Web客户访问受保护的Web资源时,浏览器弹出的登录对话框类型。
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>HelloApp realm</realm-name>
</login-config>
<login-config>元素的各个子元素的说明见下表:
属性 | 说明 |
---|---|
<auth-method> | 指定验证方法,它有3个可选值:BASIC(基本验证),DIGEST(摘要验证),FORM(基于表单的验证) |
<realm-name> | 指定安全域的名称 |
<form-login-config> | 当验证方法为FORM时,配置验证网页和出错网页 |
<form-login-page> | 当验证方法为FORM时,配置验证网页 |
<form-error-page> | 当验证方法为FORM时,配置出错网页 |
基本验证
如果Web应用采用基本验证,那么当客户访问受保护的资源时,浏览器会先弹出一个对话框,要求用户输入用户名和口令。当三次尝试失败后,会显示一个错误消息网页。在网络上传送的用户名和口令数据采用 Base64编码(全是可读文本),因此这种验证方法不是非常安全。
摘要验证
摘要验证方法和基本验证的区别在于:前者不会在网络中直接传输用户的口令,而是首先采用 MD5对用户的口令进行加密,然后传输加密后的数据,这种验证方法显然更为安全。
基于表单的验证
基于表单的验证方法和基本验证方法的区别在于:前者使用自定义的登录页面来代替标准的登录对话框。
用户自定义的验证网页中必须提供一个登录表单,表单中和用户名对应的文本框必须命名为 j_username,和口令对应的文本框必须命名为 j_password,并且表单的 action值必须为 j_security_check。如下usercheck.jsp:
<html> <head> <title>Login Page for helloapp</title> </head> <body bgcolor="white"> <form method="POST" action=j_security_check> <table border="0" cellspacing="5"> <tr> <th align="right">Username:</th> <td align="left"><input type="text" name="j_username"></td> </tr> <tr> <th align="right">Password:</th> <td align="left"><input type="password" name="j_password"></td> </tr> <tr> <td align="right"><input type="submit" value="Log In"></td> <td align="left"><input type="reset" value="reset"></td> </tr> </table> </form> </body> </html>
错误处理页面error.jsp如下:
<!--设置中文输出-->
<%@ page contentType="text/html; charset=GB2312" %>
<html><head><title>Error Page</title></head>
<body>
<p>
请输入合法的用户名和口令
</p>
</body></html>
web.xml配置如下:
<login-config>
<auth-method>FORM</auth-method>
<realm-name>HelloApp realm</realm-name>
<form-login-config>
<form-login-page>/usercheck.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
最后,应该在web.xml中加入<security-role>元素,指明这个 Web应用引用的所有角色名字。例如在Tomcat的<CATALINA_HOME>/webapps/webapps/manager应用中声明引用了 manager-script 角色:
<security-role>
<description>
The role that is required to access the text Manager pages
</description>
<role-name>manager-script</role-name>
</security-role>
内存域是由 org.apache.catalina.realm.MemoryRealm 类来实现。MemoryRealm 类从一个XML文件中读取用户信息。默认情况下,该XML文件为<CATALINA_HOME>/conf/tomcat-users.xml。以下是tomcat-users.xml文件中的代码:
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users><!--设定用户信息-->
<role rolename="manager-gui"/><!--定义角色-->
<role rolename="manager-script"/>
<user username="tomcat" password="tomcat" roles="manager-gui,manager-script"/>
</tomcat-users>
在以上 XML文件中,定义了两个角色和一个名为“tomcat”的用户(包括用户名和口令),该用户拥有 manager-gui 和 manager-script 角色。因此 Web客户能以 “tomcat” 用户的身份访问这两个角色中的相关资源。
接下来在应用的 META-INF/context.xml文件的<Context>元素内加上如下<Realm>元素:
<!-- Memory Realm -->
<Realm className="org.apache.catalina.realm.MemoryRealm" />
下面总结配置 MemoryRealm的步骤:
(1)按上面的步骤在你的应用程序的web.xml中配置安全约束,可以采用三种验证(Basic、Digest、基于表单Form)中的任一种。
(2)在<CATALINA_HOME>/conf/tomcat-user.xml 文件中定义用户、角色以及两者的映射关系。
(3)在server.xml 中配置<Realm>元素,指明使用的域。
JDBC Realm 通过 JDBC驱动程序访问存放在关系型数据库中的安全验证信息。JDBC域使得安全配置非常灵活。当修改了数据库中的安全认证信息后,不必重启tomcat服务器(两者是相互独立的)。
当用户第一次访问受保护的资源时,Tomcat将调用Realm 的authenticate()方法,该方法从数据库中读取最新的安全认证信息。该用户通过认证之后,在用户访问Web资源期间,用户的各种验证信息被保存在缓存中。
创建数据库和创建两张表: users(定义用户信息,包括用户名和口令)和 users_roles (定义用户和角色的映射关系)。
将所用的数据库驱动程序拷贝到Tomcat安装目录下/lib 中,,在 server.xml中加入如下<Realm>元素
<!-- JDBC Realm -->
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost/tomcatusers?useSSL=false"
connectionName="dbuser" connectionPassword="1234"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name" />
<Realm>元素的各个属性说明见下表:
属性 | 描述 |
---|---|
className | 此Realm实现的类名,对JDBC而言,必须是org.apache.catalina.realm.JDBCRealm |
connectionName | 来建立JDBC连接数据的用户名 |
connectionPassword | 用来建立JDBC连接的数据库密码 |
connectionURL | 用来建立JDBC连接的数据库URL |
digest | 设定储存口令时的加密方式(SHA、MD2或只有MD5) |
driverName | JDBC驱动程序类名 |
roleNameCol | 在 user_role 表中代表角色的字段名 |
userNameCol | 在 user 和 user_roles 表中代表用户名字的字段名 |
userCredCol | 在 user 表中代表用户口令的字段名 |
userRoleTable | 指定用户与角色映射关系的表 |
userTable | 指定用户名 |
DataSource域和JDBCRealm 域的两者的不同是访问数据库的方式不一样:DataSourceRealm通过
JNDI DataSource 来访问数据库;而JDBCRealm通过JDBC 驱动程序来访问数据库。
DataSource域配置步骤︰
(1)按上面的步骤在你的应用程序的web.xml 中配置安全约束,可以采用三种验证(Basic、Digest、Form)中的任一种。
(2)创建数据库和创建两张表:users(定义用户信息,包括用户名和口令)和 users_roles(定义用户和角色的映射关系)。
(3)将所用的数据库驱动程序拷贝到Tomcat安装目录下/lib 中。
(4)数据源的配置
数据源的配置涉及修改server.xml和web.xml文件。创建一个名为 jdbc/tomcatusers 的 DataSource,需要在server.xml中<GlobalNamingResources>元素下加入<Resource>元素:
<GlobalNamingResources>
......
<Resource name="jdbc/tomcatusers" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="dbuser" password="1234"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/tomcatusers?autoReconnect=true&useSSL=false"/>
</GlobalNamingResources>
<!-- DataSource Realm -->
<Realm className="org.apache.catalina.realm.DataSourceRealm"
dataSourceName="jdbc/tomcatusers"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
为DataSourceRealm配置DataSource,需要注意以下几点:
当通过验证的用户访问Web资源时,HttpServletRequest对象的 getRemoteUser()方法可以返回访问当前网页的用户的名字。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。