Tomcat中的领域(Realm)

Easter79
• 阅读 714

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

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

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

UserDatabaseRealm

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

server.xml中resource的声明:

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

server.xml中UserDatabaseRealm的配置:

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

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

<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
    <role rolename="tomcat"/>
    <role rolename="role1"/>
    <user username="tomcat" password="tomcat" roles="tomcat"/>
    <user username="both" password="tomcat" roles="tomcat,role1"/>
    <user username="role1" password="tomcat" roles="role1"/>
</tomcat-users>

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

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

JDBCRealm

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

server.xml中JDBCRealm的配置:

<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"  
       driverName="com.mysql.jdbc.Driver"  
       connectionURL="jdbc:mysql://localhost:3306/DB_NAME"  
       connectionName="DB_Username" 
       connectionPassword="DB_Password"  
       userTable="TABLE_Name"
       userNameCol="COLUMN_Username"      
       userCredCol="COLUMN_Password"  
       userRoleTable="ROLE_TABLE_Name" 
       roleNameCol="COLUMN_Role" />  

DataSourceRealm

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

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

create table users (
    user_name varchar(15) not null primary key,
    user_pass varchar(15) not null
);

create table user_roles (
    user_name varchar(15) not null,
    role_name varchar(15) not null,
    primary key (user_name, role_name)
);

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

server.xml中配置DataSourceRealm:

<Realm className="org.apache.catalina.realm.DataSourceRealm"
    dataSourceName="jdbc/authority"
    userTable="users" 
    userNameCol="user_name" 
    userCredCol="user_pass"
    userRoleTable="user_roles" 
    roleNameCol="role_name"/>

JNDIRealm

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

server.xml中JNDIRealm的配置:

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

JAASRealm

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

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

CombinedRealm

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

<Realm className="org.apache.catalina.realm.CombinedRealm" >
   <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
        resourceName="UserDatabase"/>
   <Realm className="org.apache.catalina.realm.DataSourceRealm"
        dataSourceName="jdbc/authority"
        userTable="users"
        userNameCol="user_name" 
        userCredCol="user_pass"
        userRoleTable="user_roles" 
        roleNameCol="role_name"/>
</Realm>

LockOutRealm

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

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

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

参考链接:

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
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
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k