JavaWeb-Tomcat安全域
概述
安全域是Web
服务器用来保护Web
资源的一种机制.
在安全域中可以配置安全验证信息,即用户信息(包括用户名和口令),以及用户和角色的映射关系.
每个用户可以有一个或多个角色,每个角色限定了可访问的Web
资源,一个用户可以访问其拥有的所有角色对应的资源.
安全域是Tomcat
内置的功能,在org.apache.catalina.Realm
接口中声明了把一组用户名,口令及所关联的角色集成到Tomcat
中的方法.
安全域的类型
- JDBCRealm: 通过
JDBC
驱动程序访问存放在数据库中的安全验证信息 - DataSourceRealm: 通过
JNDI
数据源访问存放在数据库中的安全验证信息 - JNDIRealm: 通过
JNDI provider
访问存放在基于LDAP
的目录服务器中的安全验证信息 - UserDatabaseRealm
- MemoryRealm: 在初始化阶段,从
XML
文件中读取安全验证信息,并把它们以一组对象的形式存放在内存中 - JAASRealm: 利用
JAAS(Java Authentication & Authorization Service,Java验证与授权服务)
框架进行验证 - CombinedRealm
- LockOutRealm
不管配置哪一种类型的安全域,都包含以下步骤
-
在
Web
应用的WEB-INF/web.xml
文件中为Web
资源设置安全约束 -
在
Tomcat
的$CATALINA_HOME/conf/server.xml
配置文件中,或者Web
应用的META-INF/contex.xml
文件中配置<Realm>
元素,并在这个元素中指定安全域的类名及相关的属性.形式如下:<Realm className="xxxRealm" 其他属性...>
<Realm>
可以嵌入到3中不同的容器元素中,这直接决定<Realm>
的作用范围:
嵌入位置 | 描述 |
---|---|
嵌入到<Engine> 元素中 |
<Engine> 中所有虚拟主机上的所有Web 应用共享这个Realm ,例外情况是在这个<Engine> 下的<Host> 活<Context> 元素下还定义了自己的Realm 元素 |
嵌入<Host> |
<Host> 下的所有Web 应用共享这个Realm ,例外情况是在这个<Host> 下的<Context> 元素下还定义了自己的Realm 元素 |
嵌入到<Context> |
只有<Context> 元素对应的Web 应用才能使用这个Realm |
为Web资源设置安全约束
无论是哪种域,都必须先配置安全约束.用来定义受保护的资源,允许访问的角色及给用户提供登录渠道.
在Web
应用的$project_base_dir/src/main/webapp/WEB-INF/web.xml
文件中加入<security-constraint>
,<login-config>
和<security-role>
元素.
直接参考配置安全约束,配置安全验证登录界面和配置对安全验证角色的引用
配置好了安全约束,就可以试试配置各个安全域了.
内存域
由org.apache.catalina.realm.MemoryRealm
类来实现,从一个XML
文件中读取用户信息,在默认的情况下,改XML
文件为$CATALINA_HOME/conf/tomat-users.xml
,参考:Tomcat用户角色配置
JDBC域
JDBC
域通过JDBC
驱动程序访问存放在关系型数据库中的安全验证信息.
用户数据库结构
一般需要在数据库中创建两张表:users
和user_roles
,这两张表包含了所有的安全验证信息.
其实表名列名也可以自由命名,但需要与<Realm>
元素的对应的属性值保持一致.
users
字段 | 字段类型 | 描述 |
---|---|---|
user_name |
varchar(15) |
用户名 |
user_pass |
varchar(15) |
密码 |
user_roles
字段 | 类型 | 描述 |
---|---|---|
user_name |
varchar(15) |
用户名 |
role_name |
varchar(15) |
角色 |
配置<Realm>元素
当用户数据库创建好后,应该把数据库的驱动程序(jar
)文件复制到$CATALINA_HOME/lib
目录中,然后再在$CATALINA_HOME/conf/server.xml
文件的<Engine>
/<Host>
或<Context>
元素内加入如下<Realm>
元素:
<Realm className="org.apache.catalina.realm.JDBCRealm"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost:3306/authority?user=dbuser&password=dbpass"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
表明用户在输入用户名密码后与端口号为3306
的MySQL
中找到authority
数据库,查找users
和user_roles
两张表对应的信息是否一致,一致则放行.
更多域配置参考官网realm-howto