Tomcat中的领域(Realm)

Servlet container和Web应用程序本身都可以控制Web应用程序资源的安全防护。在J2EE规范中,前者成为容器管理(container-managed)的安全防护,后者称为应用程序管理(application-managed)的安全防护。为了使用Tomcat的容器管理的安全防护机制,必须设定领域。领域只是用户、密码和角色的集合。

Tomcat包含以下几个常见的领域实现:UserDatabaseRealm、JDBCRealm、JNDIRealm与JAASRealm。另外,开发者可以创建额外的领域实现,以便作为其用户和密码的接口。领域在server.xml文件中以<Realm>元素指定:

1<Realm className="some.realm.implementation.className" 2 customAttribute1="some value" 3 customAttribute2="other value"/>

UserDatabaseRealm

UserDatabaseRealm是从静态文件加载到内存中的,且直到Tomcat停止后才从内存中清除。事实上,Tomcat所用的用户、密码及角色只存在于内存中,换句话说,权限文件只会在启动时读入一次。在UserDatabaseRealm中分配权限的默认文件为$CATALINA_HOME/conf/tomcat-users.xml。

server.xml中resource的声明:

1<Resource name="UserDatabase" auth="Container" 2 type="org.apache.catalina.UserDatabase" 3 description="User database that can be updated and saved" 4 factory="org.apache.catalina.users.MemoryUserDatabaseFactory" 5 pathname="conf/tomcat-users.xml" />

server.xml中UserDatabaseRealm的配置:

<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>

tomcat-users.xml中users和roles的配置:

1<tomcat-users xmlns="http://tomcat.apache.org/xml" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" 4 version="1.0"> 5 <role rolename="tomcat"/> 6 <role rolename="role1"/> 7 <user username="tomcat" password="tomcat" roles="tomcat"/> 8 <user username="both" password="tomcat" roles="tomcat,role1"/> 9 <user username="role1" password="tomcat" roles="role1"/> 10</tomcat-users>

user和password的意义很清楚了,不过这里要解释一下有关roles的含义。角色(roles)是一组用户,针对这组用户,Web应用程序可以定义一组特定的功能组合。

UserDatabaseRealm并非真正用于实际,因为它唯一的更新方式是编写能经由JNDI访问Realm的自定义servlet。而该servlet需要能修改内存中的用户数据库,或磁盘上的tomcat-users.xml文件,最后,还需要重启Tomcat以便使这些修改生效。

JDBCRealm

顾名思义,JDBCRealm是一个可以使用关系型数据库的领域。它比UserDatabaseRealm更灵活,并且能动态的访问数据库。例如:往数据库中新增一个账号,JDBCRealm就可以马上读取它。

server.xml中JDBCRealm的配置:

1<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99" 2 driverName="com.mysql.jdbc.Driver" 3 connectionURL="jdbc:mysql://localhost:3306/DB_NAME" 4 connectionName="DB_Username" 5 connectionPassword="DB_Password" 6 userTable="TABLE_Name" 7 userNameCol="COLUMN_Username" 8 userCredCol="COLUMN_Password" 9 userRoleTable="ROLE_TABLE_Name" 10 roleNameCol="COLUMN_Role" />

DataSourceRealm

这是一个通过JNDI访问配置好的数据源,来访问关系型数据库的一种Realm实现。

假如有个MySQL数据库叫"authority",并且包含下面的表:

1create table users ( 2 user_name varchar(15) not null primary key, 3 user_pass varchar(15) not null 4); 5 6create table user_roles ( 7 user_name varchar(15) not null, 8 role_name varchar(15) not null, 9 primary key (user_name, role_name) 10);

如果可以通过JNDI方式以"java:/comp/env/jdbc/authority"访问,此时:

server.xml中配置DataSourceRealm:

1<Realm className="org.apache.catalina.realm.DataSourceRealm" 2 dataSourceName="jdbc/authority" 3 userTable="users" 4 userNameCol="user_name" 5 userCredCol="user_pass" 6 userRoleTable="user_roles" 7 roleNameCol="role_name"/>

JNDIRealm

如果需要Tomcat从LDAP(Lightweight Directory Access Protocol,轻量目录访问协议)目录取得用户名称、角色及密码,则可以使用JNDIReam。它是一个非常有弹性的Realm实现,可以依据用户名、角色及密码的LDAP目录来验证用户的身份。同时还允许该数据用于许多不同的模式布局。它还可以递归的搜寻LDAP的层次目录,直到找到所需的信息为止。还可以在特定服务器的特定位置查找。

server.xml中JNDIRealm的配置:

1<Realm className="org.apache.catalina.realm.JNDIRealm" 2 connectionURL="ldap://localhost:389" 3 userPattern="uid={0},ou=people,dc=mycompany,dc=com" 4 roleBase="ou=groups,dc=mycompany,dc=com" 5 roleName="cn" 6 roleSearch="(uniqueMember={0})"/>

JAASRealm

JAASRealm是经由JAAS(Java Authentication and Authorization Service,Java验证与授权服务)验证用户的一种领域实现。JAAS实现了标准的“可插入式验证模块(Pluggable Authentication Module,PAM)”架构,此架构可让应用程序独立于验证实现之外。可以不修改应用程序本身而只需稍微修改应用程序的配置,在应用程序中插入全新或更新的验证实现。除此之外,JAAS还支持堆栈式的验证模块,从而在一个验证堆栈中,多个验证模块可以相互协同使用。

1<Realm className="org.apache.catalina.realm.JAASRealm" 2 appName="MyFooRealm" 3 userClassNames="org.foobar.realm.FooUser" 4 roleClassNames="org.foobar.realm.FooRole"/>

CombinedRealm

这是一个特殊的Realm,顾名思义,它可以使用多个子的Realm(Realm可以嵌套)来对用户进行授权。也许你有多个“数据源”,也许你希望当有一个Realm停止工作的时候系统仍然不会崩溃,不管是什么需求需要同时使用多个Realm,这个CombinedRealm就能满足这个需求。授权将会按照子Realm的声明顺序依次进行,只要满足任何一个子Realm,都可以通过校验。

1<Realm className="org.apache.catalina.realm.CombinedRealm" > 2 <Realm className="org.apache.catalina.realm.UserDatabaseRealm" 3 resourceName="UserDatabase"/> 4 <Realm className="org.apache.catalina.realm.DataSourceRealm" 5 dataSourceName="jdbc/authority" 6 userTable="users" 7 userNameCol="user_name" 8 userCredCol="user_pass" 9 userRoleTable="user_roles" 10 roleNameCol="role_name"/> 11</Realm>

LockOutRealm

它继承与CombinedRealm,和CombinedRealm一样,与它一起工作的Realm需要嵌套在LockOutRealm中,而且也是只需要满足任何一个Realm即可。如果在一定的时间内多次尝试授权失败,它将会锁定这个用户。使用它时,不需要修改它下面的Realm配置,因为它是通过记录所有失败的登录(包括不存在的用户)来实现的。

下面是安装Tomcat后,server.xml中默认的配置:

1<!-- Use the LockOutRealm to prevent attempts to guess user passwords via a brute-force attack --> 2<Realm className="org.apache.catalina.realm.LockOutRealm"> 3 <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key 4 "UserDatabase". Any edits that are performed against this UserDatabase are immediately 5 available for use by the Realm. --> 6 <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> 7</Realm>

参考链接:

http://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html#UserDatabaseRealm

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )