(8) tomcat中管理领域、角色及用户
srverlet Container或web应用程序本身都可以提供控制web应用程序资源的安全防护
前者称为容器管理的安全防护,或者称为应用程序管理安全防护
通过内嵌机制,tomcat提供一些安全防护方法,这是一种“容器管理”的安全防护。另一方面如果有一系列具有自己的登录机制的servlet和JSP,则视为应用程序管理的安全防护。
不管是哪种安全防护类型,都是用称之为领域(realm)的组来管理用户和密码。
下面将介绍conf/server.conf中领域的配置(定义了如何存储用户与角色信息),以及web应用程序的WEB_INF/web.xml中的<security-constraint>(如何对webapp的用户进行授权)
一、领域的配置
Tomcat含有可插入式的领域架构,且具备多种有用的领域实现:
- UserDatabaseReal
- JDBCRealm
- JNDIRealm
- JAASRealm
- DataSourceRealm
- MemoryRealm
- CombinedRealm
- LockOutRealm
Java开发者可创建额外的领域实现,以便作为与其用户和密码的接口。如欲指定使用何种领域,在server.conf配置文件中插入Realm元素,以className属性设定要使用的领域,然后通过 该实现的自定义属性以提供此领域相关的配置信息:
<Realm className="SOME.REALM.IMPLEMENTATION.CLASSNAME"
CUSTOMATRRIBUTION1="SOME CUSTOM VALUE"
CUSTOMATTRIBUTION2="SOME OTHER CUSTOM VALUE"/>
后面的realm配置可以覆盖前面
每种不同的Realm 采用了不同的用户名和密码存储和使用方式,tomcat默认使用的是UserDatabaseRealm。
1、UserDatabaseRealm
UserDatabaseRealm是从静态文件加载到内存中,且直到tomcat停止后才从内存中清除。事实上,tomcat所用的用户、密码及角色只存在于内存中。换句话说,权限文件只会在启动时,读入一次,在UserDatabaseRealm中分配权限的默认文件为$CATALINA_HOME/conf/tomcat-user.xml(如果更改了tomcat-user.xml文件但没有重启tomcat,则除非重启tomcat,否则tomcat不会重启读入该文件)
tomcat-user.xml文件是使用该领域的关键。它包含一份可访问web应用程序的用户清单。该文件是一个简单的xml文件,根元素是tomcat-users,且只能使用role和user元素。
每个role元素只有一个属性:rolename。
而每个user元素则有3个属性:username、password及roles
role元素:定义rolename,即角色名称,可以定义多个
user元素:定义username用户名、password密码、roles使用上述的哪个角色(多个角色名称之间使用逗号分隔),可以定义多个
UserDatabaseRealm是基于MemoryRealm扩展出来的,默认是读取tomcat-users.xml(可通过Resource中的pathname属性配置为其它文件)里面配置的用户角色信息。
server.xml中的默认配置如下:
不过他是通过应用jndi的方式实现的,从设计上支持多种实现方式,默认采用了类似MemoryRealm的实现方式,但是又对其进行了扩展,主要是增加了“用户组”的概念,即用户除了有所属角色外,还可以有所属“用户组”,用户组可以关联其它多个角色,例如它可以使用下面的tomcat-users.xml配置:
<role rolename="tomcat"/>
<role rolename="admin"/>
<user username="tomcat"
password="tomcat" roles="tomcat"/>
<group groupname="one" roles="tomcat"/>
<user username="admin"
password="admin" roles="admin" groups="one"/>
admin用户由于关联了“one”这个用户组,“one”用户组包含角色“tomcat”,所以admin用户就拥有了“tomcat”角色。
这个安全域的配置:
1. sever.xml的GlobalNamingResources节点下添加:
<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"
/>
2.在Engine中启用该安全域的配置:
<Realm
className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
<Realm/>元素可以:
放在<Engine/>元素中,这时该Realm会被所有应用共享。
放在<Host/>元素中,会被该Host下的应用程序共享。
放在<Context/>元素中,则只有对应的应用程序能被访问
2、JDBCRealm
相对于UserDataBaseRealm而言,JDBCRealm具有更大潜在的灵活性,并能动态访问数据,基本上是使用关系型数据库的领域。这个Realm是基于数据库的,数据库中保存了用户名/密码和用户的角色,通过建立数据库的通信来维持用户角色信息
1. 所需要的数据库脚本
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)
);
insert into users( user_name , user_pass ) values ( 'admin','admin')
insert into users( user_name , user_pass ) values ( 'tomcat','admin')
insert into user_roles(user_name,role_name) values ( 'admin','admin')
insert into user_roles(user_name,role_name) values ( 'tomcat','tomcat')
2.修改tomcat中server.xml添加安全域配置(必须做,设置JDBC的连接参数设成领域的属性,也可以在webapp的context配置文件中配置):
<Realm
className="org.apache.catalina.realm.JDBCRealm"
connectionName="sa"
connectionPassword=""
connectionURL="jdbc:h2:tcp://localhost//home/conquer/mine/work_space/h2-dbpath/tomcat"
driverName="org.h2.Driver"
userTable="users"
userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
</Realm>
领域属性详解:
className 此Realm实现的java类名,对JDBC而言,必须是org.apache.catalina.realm.JDBCRealm
connectionName 用来建立JDBC连接数据的用户名
connectionPassword 用来建立JDBC连接的数据库密码
connectionURL 用来建立JDBC连接的数据库URL
digest 摘要算法(SHA、MD2或只有MD5),默认值是cleartext
driverName JDBC驱动程序的java类名
roleNameCol 含有角色名(指定给用户)的角色表中的字段名
userNameCol 在用户与角色数据表中,列出用户名的字段名
userCredCol 在用户数据表中,列出用户密码的字段名
userRoleTable 将角色映射至用户的数据表名
userTable 列出用户与密码的数据表名
注意事项:
在配置Tomcat的JDBCRealm的时候,有几个应该注意的地方
1). 数据库JDBC驱动应该放在${tomcat.home}/server/lib目录下,而不能放在webapps的lib目录下,二者的class loader不同
2). tomcat在启动时只会自动装载后缀为.jar的jar包,因此如果使用oracle9i的驱动,应把class12.zip改名为class12.jar
3). 最好将JDBCRealm的配置信息放在webapp的context配置文件中,而不要放在server.xml中
4)<Realm/>元素可以放在<Engine/>元素中,这时该Realm会被所有应用共享。
放在<Host/>元素中,会被该Host下的应用程序共享。
放在<Context/>元素中,则只有对应的应用程序能被访问
3、JNDIRealm
如果让tomcat从LDAP目录中获取用户名称、密码及角色,可使用JNDIRealm。
JNDIRealm是非常有弹性的Realm实现,可以依据用户名、密码及角色的LDAP目录来验证用户的身份,同时还允许该数据用于许多不同的模式布局。
JNDIRealm可递归地搜索LDAP层次目录,直到找到所需要的信息为止,
或者可以设定在目录服务器的特定位置中查找
可以将密码存储为明码形式,并使用基本验证,或存储层摘要编码形式,而使用摘要验证法
其它示例:
领域属性详解:
className 此领域实现的Java类名,对于JNDIRealm,必须是org.apache.catalina.realm.JNDIRealm
connectionName 用来验证只读的LDAP连接的用户名,如果未设定则会建立匿名连接
connectionPassword 用来建立只读的LDAP连接密码
connectionURL 用来建立LDAP连接的目录URL
conetextFactory 用于此连接的JNDI程序厂商的完全限定的java类名,如果未设定则使用默认的JNDI
LDAP提供商类
digest 摘要算法(SHA、MD2或MD5),默认值是cleartext
roleBase 查询角色信息的LDAP基本目录条目,如果未指定,默认使用目录范围中的顶层元素
roleName 搜寻包含角色名的领域属性名,此属性可与userRoleName合并使用,若未指定,则只会从用户的目录中取得角色
userRoleName 在用户目录中包含关联用户角色名的属性名,含有此用户角色名称的用户目录中的属性名称。
此属性可与roleName合并使用。如果未设定,则用户的所有角色都来自角色搜索
roleSubtree 如果想要从用户相关的角色的roleBase中以递归方式检索设定的元素的子树,则需要设为true。
如果未设定,则导致默认值false只会搜寻最上层(非递归方式的搜寻)
userPattern 用户目录识别名(DN,distinguished
name)的样式,遵从java.text.MessageFormat的语法,用{0}标记插入的实际用户名
userPassword 属性名,用户目录中包含的用户口令。
如果设定此值,则JNDIRealm会用connectionName与connectionPassword属性的指定值绑定至目录,并从目录服务器中获取对应的口令属性,以便与正在被验证的用户指定的属性值比对。如果设定了digest属性,则在比对用户提供的密码与获取自目录服务器的属性值之前,会先对改密码应用摘要算法;如果未设定则JNDIRealm会以用户目录的DN以及用户指定的密码尝试单纯第绑定至目录
userBase 设定以userSearch表达式搜寻用户的基本元素。如果未设定,则会使用目录范围中的顶层元素;如果使用userPattern表达式,则会忽略此属性
userSearch 当搜索用户目录时,所有的LDAP过滤表达式,以{0}标记实际插入用户名的位置,
使用此属性(以及userBase和userSubtree属性)代替userPattern属性,从目录中检索用户目录
userSubtree 如果想递归检索用户目录的userBase属性指定的元素子树,则需要设置该值为true。
默认为false,导致仅检索元素子树的顶层(非递归检索)。如果使用userPattern表达式,则会忽略此属性
4、JAAS Realm
这个是基于java的jaas认证和授权服务而设计的,主要就是用到了jaas的“认证”部分,不涉及“授权”,通过向javax.security.auth.Subject#getPrincipals()里面添加用户和角色来完成用户和角色的认证
注意这里的技巧在于,tomcat要在server.xml的该安全域里配置哪些java类型的Principal表示用户,哪些java类型的Principal表示角色,因为jaas的登录模块在验证成功后只能将用户和角色信息都放入到javax.security.auth.Subject#getPrincipals(),通过事先的类型约定来让tomcat识别用户和角色信息。
JAAS实现了标准的“可插入式验证模块”(PAM)架构,此架构可让应用程序独立于验证实现之外,可不经修改应用程序应用程序本身而只需稍微修改应用程序配置设定,在应用程序中插入全新或更新的验证实现(此时为Tomcat),如依据unix的用户/密码/组 数据库,可使用配置好的JAASRealm,验证用户身份,然后更改配置设定,而不需要更改整个领域实现即可重新设定成依据Kerberos来验证。
除此之外,JAAS还支持堆栈式的验证模块,从而在一个验证堆栈中,两个或三个验证模块可以彼此协同使用。对插入式模块进行堆栈处理,允许实现tomcat尚未实现的自定义验证逻辑
这个安全域的配置如下:
<Realm
className="org.apache.catalina.realm.JAASRealm"
appName="Sample"
userClassNames="jaas.SamplePrincipal"
roleClassNames="jaas.SampleRolePrincipal"/>
可以看到,上面的配置中指定了jaas.SamplePrincipal表示用户,而jaas.SampleRolePrincipal表示角色。
可通过confiFile属性来配置jaas需要的认证配置文件,或使用java默认-Djava.security.auth.login.config=xx/jaas.config参数来指定领域属性详解:
className 此领域实现的java类名,对于JAASRealm必须是org.apache.catalina.realm.JAASRealm
appName 传给JAAS LoginContext构造函数(并基于JAAS配置挑选适当的登录方法)的应用程序名称。
默认是Tomcat,不过只要在JAAS .java.login.config文件中更改对应名,即可设定成任何所要的值
userClassNames 代表个别用户的javax.security.Principal类清单,以逗号分隔。对于UnixLoginModule设定值,应当包括UnixPrincipal类类
roleClassNames 代表安全角色的javax.security.Principal类清单,以逗号分隔。对于UnixLoginModule,设定值应该包括UnixNumericGroupPrincipal类
userContextClassLoader 告知JAASRealm,或从前后类加载器中加载类,或从Tomcat自身的类加载器加载类,默认值为true
关于jaas的登录模块的实现,请看:
Java认证和授权服务
JAAS 之 认证http://blog.csdn.net/conquer0715/article/details/78204889
Java认证和授权服务JAAS之授权http://blog.csdn.net/conquer0715/article/details/78205755
注意:如果要使用Java认证和授权服务JAAS之认证中的例子,需要进行如下更改:
1. MyLoginModule 文件:
package jaas; import javax.security.auth.Subject; import javax.security.auth.callback.*; import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import java.security.Principal; import java.util.Map; public class MyLoginModule implements LoginModule { // username and password private String username; private char[] password; // the authentication status private boolean userPwdSucceeded = false; private boolean commitSucceeded = false; // user's Principal private Principal userPrincipal; // initial state private Subject subject; private CallbackHandler callbackHandler; /** * Initialize this <code>LoginModule</code>. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<java.lang.String, ?> sharedState, Map<java.lang.String, ?> options) { this.subject = subject; this.callbackHandler = callbackHandler; } /** * Authenticate the user by prompting for a user name and password. */ public boolean login() throws LoginException { // prompt for a user name and password if (callbackHandler == null) throw new LoginException("Error: no CallbackHandler available " + "to garner authentication information from the user"); Callback[] callbacks = new Callback[]; callbacks[] = new NameCallback("user name"); callbacks[] = new PasswordCallback("password", false); // callbacks[2] = new TextOutputCallback(TextOutputCallback.INFORMATION, "hello, just a msg!"); // callbacks[3] = new TextOutputCallback(TextOutputCallback.WARNING, "just warn you!"); try { callbackHandler.handle(callbacks); NameCallback nameCallback = (NameCallback) callbacks[]; PasswordCallback passwordCallback = (PasswordCallback) callbacks[]; username = nameCallback.getName(); char[] tmpPassword = passwordCallback.getPassword(); passwordCallback.clearPassword();// clean password in memory space if (tmpPassword == null) { tmpPassword = new char[];// treat a NULL password as an empty password } password = new char[tmpPassword.length]; System.arraycopy(tmpPassword, , password, , tmpPassword.length); } catch (Exception e) { e.printStackTrace(); } // verify the username/password // boolean usernameCorrect = false; // if (username.equals("user")) usernameCorrect = true; // // if (usernameCorrect && // password.length == 3 && // password[0] == 'p' && // password[1] == 'w' && // password[2] == 'd') { // // userPwdSucceeded = true; // } else { // userPwdSucceeded = false; // cleanUserAndPwdData(); // if (!usernameCorrect) { // throw new FailedLoginException("User Name Incorrect"); // } else { // throw new FailedLoginException("Password Incorrect"); // } // } // return userPwdSucceeded; userPwdSucceeded=true; return true; } public boolean commit() throws LoginException { if (!userPwdSucceeded) return false; // add a Principal (authenticated identity) to the Subject userPrincipal = new SamplePrincipal(username); subject.getPrincipals().add(userPrincipal); // for tomcat jaas realm if (username.equals("admin")) { subject.getPrincipals().add(new SampleRolePrincipal("admin")); } else if (username.equals("tomcat")) { subject.getPrincipals().add(new SampleRolePrincipal("tomcat")); } // in any case, clean out state cleanUserAndPwdData(); return commitSucceeded = true; } public boolean abort() throws LoginException { if (!userPwdSucceeded) return false; if (commitSucceeded) { logout(); } else { cleanState(); } return true; } public boolean logout() throws LoginException { subject.getPrincipals().remove(userPrincipal); cleanState(); userPwdSucceeded = commitSucceeded; return true; } private void cleanState() { userPwdSucceeded = false; cleanUserAndPwdData(); userPrincipal = null; } private void cleanUserAndPwdData() { username = null; if (password != null) { for (int i = ; i < password.length; i++) password[i] = ' '; password = null; } } }
SamplePrincipal 文件:
package jaas; import java.security.Principal; public class SamplePrincipal implements Principal { private String name; public SamplePrincipal(String name) { this.name = name; } public String getName() { return name; } }
SampleRolePrincipal文件:
package jaas; public class SampleRolePrincipal extends SamplePrincipal { public SampleRolePrincipal(String name) { super(name); } }
说明:
另外注意
userClassNames="jaas.SamplePrincipal" 和 roleClassNames="jaas.SampleRolePrincipal"
两个实现类的 equals 和 hascode 方法,如果覆盖不好最好不要覆盖,否则容易
subject.getPrincipals().add 不进去。
5、DataSourceRealm
这个安全域和上面的JDBCRealm实现基本一致,只不过不是创建数据库连接,而是从JNDI上下文获取数据源,它所需要的数据库脚本和JDBCRealm一致。
修改tomcat的server.xml 添加安全域配置:
1. 在 GlobalNamingResources
节点下添加:
<Resource
name="jdbc/h2"
type="javax.sql.DataSource"
username="sa"
password=""
driverClassName="org.h2.Driver"
url="jdbc:h2:tcp://localhost//home/conquer/mine/work_space/h2-dbpath/tomcat"/>
2. 继续添加安全域配置(这里会使用jndi引用上面注册的数据源资源):
<Realm
className="org.apache.catalina.realm.DataSourceRealm"
dataSourceName="jdbc/h2"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
</Realm>
6、MemoryRealm
这个是最简单的配置,默认是读取tomcat-users.xml(可通过pathname属性配置为其它文件)里面配置的用户角色信息。
修改server.xml 添加配置:
<Realm
className="org.apache.catalina.realm.MemoryRealm"/>
7、CombinedRealm
这是一个特殊的Realm,顾名思义,它可以使用多个子的Realm(Realm可以嵌套)来对用户进行授权。也许你有多个“数据源”,也许你希望当有一个Realm停止工作的时候系统仍然不会崩溃,不管是什么需求需要同时使用多个Realm,这个CombinedRealm就能满足这个需求。授权将会按照子Realm的声明顺序依次进行,只要满足任何一个子Realm,都可以通过校验。
resourceName="UserDatabase"/>
dataSourceName="jdbc/authority"
userTable="users"
userNameCol="user_name"
userCredCol="user_pass"
userRoleTable="user_roles"
roleNameCol="role_name"/>
8、LockOutRealm
它继承于CombinedRealm,和CombinedRealm一样,与它一起工作的Realm需要嵌套在LockOutRealm中,而且也是只需要满足任何一个Realm即可。如果在一定的时间内多次尝试授权失败,它将会锁定这个用户。使用它时,不需要修改它下面的Realm配置,因为它是通过记录所有失败的登录(包括不存在的用户)来实现的。
二、web.xml的配置
web.xml安全配置
Servlet规范支持安全地访问web资源,只需要通过web.xml简单配置即可,其功能由服务器提供商实现,
web.xml文件内容如下:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app>
<--!配置 <security-constraint/> 元素,指定角色可访问的资源集和可使用的 HTTP 方法--> <security-constraint> <web-resource-collection> #定义资源集 <web-resource-name>some name</web-resource-name> #指定资源名称 <url-pattern>*.jsp</url-pattern> #匹配资源 <url-pattern>*.do</url-pattern> <http-method>GET</http-method> #可使用的HTTP方法 <http-method>PUT</http-method> <http-method>HEAD</http-method> <http-method>TRACE</http-method> <http-method>POST</http-method> <http-method>DELETE</http-method> <http-method>OPTIONS</http-method> </web-resource-collection> <auth-constraint> #定义认证用户 <role-name>tomcat</role-name> <role-name>admin</role-name> </auth-constraint> tomcat或admin两个角色都可以使用GET|PUT|HEAD|TRACE|POST|DELETE|OPTIONS方法访问*.jsp *.do资源 <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> <!-- 这个可选的元素指出在访问相关资源时使用哪种传输层保护。 它必须包含一个transport-guarantee子元素(合法值为NONE | INTEGRAL | CONFIDENTIAL), transport-guarantee为NONE值将对所用的通讯协议不加限制。 INTEGRAL值表示数据必须以一种防止截取它的人阅读它的方式传送。 虽然原理上(并且在未来的HTTP版本中),在INTEGRAL和CONFIDENTIAL之间可能会有差别,但在当前实践中,他们都只是简单地要求用SSL。 --> </user-data-constraint> </security-constraint> #对一个完整资源的安全的定义结束 <security-constraint> #对另一个资源安全的定义开始 <web-resource-collection> #定义资源集 <web-resource-name>admin page</web-resource-name> #定义资源名称
<url-pattern>/admin.jsp</url-pattern> #资源匹配 </web-resource-collection> <auth-constraint> #定义认证用户 <role-name>admin</role-name> </auth-constraint> </security-constraint> #该资源集安全定义结束,admin.jsp资源只能由admin角色访问 <security-constraint> #第三个资源安全定义开始 <web-resource-collection> #定义资源集 <web-resource-name>tomcat page</web-resource-name> #定义资源名称 <url-pattern>/tomcat.jsp</url-pattern> #匹配资源 </web-resource-collection> <auth-constraint> #定义认证用户 <role-name>tomcat</role-name> </auth-constraint> </security-constraint> #该资源安全定义结束 ,tomcat.jsp资源只能由tomcat角色访问 配置 <login-config/>元素,指定认证方式,并指定安全域 <login-config> <!--<auth-method>BASIC</auth-method>--> <auth-method>FORM</auth-method> 目前认证方式有4种:BASIC(基础认证)|DIGEST(摘要认证)|FROM(表单认证)|CLIENT-CERT(证书认证)
1、BASIC(基础认证):需要提供base64编码文本的用户口令,这种验证方法,所有的密码都会以base64编码文本在网络上传递
示例如下:
2、DIGEST(摘要认证):需要提供摘要编码字符串的用户口令,若使用摘要认证,除了在此web.xml文件中设置外,还需要在server.xml文件中修改Realm设定,将digest属性添加到Realm元素中
并给与该属性MD5值,digest属性值可使用SHA/MD2/MD5,推荐仅使用MD5,在tomcat的密码库(codebase)中对该选项的支持更好
除了告诉tomcat存储密码的方式(MD5)外,还需要以指定格式手动加密每个用户密码,对于每个用户均需执行如下两个步骤:
步骤1:
$CATALINA_HOME/bin/digest.sh -a MD5 123456 #123456是明文密码,执行后返回加密密码
步骤2:将上述冒号后的加密后的密码复制添加到tomcat-user.xml文件中作为某个用户的密码
示例如下:
3、FROM(表单认证):在网页的表单上要求提供用户密码
当用户请求web应用程序受保护的资源时,表单验证会显示登录表单的网页画面,在web应用程序中,为实现表单验证,需要登录表单的网页与验证失败的错误信息网页
示例:
/login.html,form-login-page元素表示当tomcat发现未登录的用户企图访问受到security-constraint保护保护的资源时,需要显示给用户的网页
/error.html,form-error-page元素表示当用户登录失败时,tomcat要显示给用户的网页
4、CLIENT-CERT(证书认证):以客户端数字证书来确认用户的身份
只有当在SSL(即HTTPS)上提供网页内容时,才能使用CLIENT_CERT的验证方(在web.xml文件的auth-method元素中的CLIENT_CERT),它允许客户端认证不用口令,而是浏览器提供客户端X.509数值认证证书作为登录认证
<!-- 使用的Realm名字,注意这里不能有空格 -->
<realm-name>MyConstraints</realm-name>
<form-login-config> #只有表单验证(FROM),才需要这里的登录表单网页和验证失败错误信息网页 相对于Web应用程序的根目录的2个文件
<form-login-page>/login.html</form-login-page> #该元素表示当tomcat发现未登录的用户企图访问受到security-constraint保护保护的资源时,需要显示给用户的网页
<form-error-page>/error.html</form-error-page> #用户登录失败时,form-error-page元素展示了tomcat要显示给用户的网页
</form-login-config>
</login-config> 配置<security-role/>元素来定义角色(角色是在tomcat-user.xml文件中事先定义好的) <security-role>
<role-name>tomcat</role-name>
</security-role>
<security-role>
<role-name>admin</role-name>
</security-role> </web-app>
上述的web.xml文件内容表示:
1、安全规则
admin.jsp 只能由 admin 角色访问,
tomcat.jsp 只能由 tomcat 角色访问,
其它任意 *.jsp *.do 可由 admin 或 tomcat 角色访问。
2、认证方式
BASIC 是基础认证方式,由浏览器厂商实现的用户名和密码接收界面;
FORM 是应用定制的用户名和密码接收页面;
3、角色声明
必需明出所有用到的角色
(8) tomcat中管理领域、角色及用户的更多相关文章
- asp.net Identity2 角色(Role)的使用(二)角色管理,角色控制器和视图
新建一个AdminViewModel 文件,建立视图模型类 public class RoleViewModel { public string Id { get; set; } [Required( ...
- Tomcat学习笔记 - 错误日志 - NetBeans配置tomcat出错情况总结 -- 尚未授予访问 Tomcat 服务器的权限。请在服务器管理器的 Tomcat 定制器中设置 "manager-script" 角色的正确用户名和口令。 有关详细信息, 请查看服务器日志。
错误描述: 发布时控制台出现: 部署错误: 尚未授予访问 Tomcat 服务器的权限.请在服务器管理器的 Tomcat 定制器中设置 "manager-script" 角色的正确用 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(22)-为用户设置角色
ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 (2):数据库访问层的设计Demo (3):面向接口编程 (4 ):业务逻辑层的封装 ...
- JavaWeb学习之tomcat安装与运行、tomcat的目录结构、配置tomcat的管理用户、web项目目录、虚拟目录、虚拟主机(1)
1.tomcat安装与运行双击tomcat目录下的bin/startup.bat,启动之后,输入http://localhost:8080,出现安装成功的提示,表示安装tomcat成功 2.tomca ...
- How Tomcat works — 八、tomcat中的session管理
在使用shiro的session的时候感觉对于tomcat中session的管理还不是特别清楚,而且session管理作为tomcat中比较重要的一部分还是很有必要学习的. 目录 概述 session ...
- [转]Sql Server 2005中的架构(Schema)、用户(User)、登录(Login)和角色(Role)
每一个概念的产生必然是因为碰到了无法解决的问题.换句话说,如果没有它,必然会导致某些问题难以解决.所以我想从这个角度切入,希望能把这几个复杂而暧昧的多角关系从最实用的角度来阐述清楚. 在问题的最初,我 ...
- Oracle用户管理和角色管理
原博:http://liwx.iteye.com/blog/1182251 一.创建用户的Profile文件 SQL> create profile student limit // stude ...
- 学习MVC之租房网站(五)-权限、角色、用户管理
在上一篇<学习MVC之租房网站(四)-实现Service层并进行单元测试>中,记录了实现Service层并进行单元测试的过程,接下来该到"正题"-MVC了,也就是UI层 ...
- JAVAEE——BOS物流项目12:角色、用户管理,使用ehcache缓存,系统菜单根据登录人展示
1 学习计划 1.角色管理 n 添加角色功能 n 角色分页查询 2.用户管理 n 添加用户功能 n 用户分页查询 3.修改Realm中授权方法(查询数据库) 4.使用ehcache缓存权限数据 n 添 ...
随机推荐
- 蒟蒻ACMer回忆录 · 一段弱校ACM的奋斗史
三年半的ACM生涯终于迎来了终点,退役之时,感慨万分,故写此文以纪念逝去的时光,那些为ACM拼搏的日子,那段弱校ACM的奋斗史. 三年半的ACM生涯,窝见证了CUMT从打铁到铜牌的突破,又见证了从铜牌 ...
- Linux下的录屏软件Kazam
发现Ubuntu下一个很好用的录屏软件kazam,Ubuntu官方源中就有. 1.安装 $ sudo apt-get install kazam 2.使用 使用很简单,除了截图,还可以录制屏幕视频.既 ...
- MyEclipse中安装SVN插件的最有效的方法
(1)下载svn插件:http://subclipse.tigris.org/files/documents/906/49209/site-1.8.8.zip (2)解压svn包,找到其中的两个文件夹 ...
- 笔记-JavaWeb学习之旅
junit单元测试 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值 白盒测试:需要些代码,关注程序具体的执行流程 Junit使用: 白盒测试 步骤: 定义一个测试类(测试用例) 定义 ...
- CentOS7下如何正确安装并启动Docker(图文详解)
我使用了CentOS 7操作系统,可以非常容易地安装Docker环境.假设,下面我们都是用root用户进行操作,执行如下命令进行准备工作: yum install -y yum-utils yum-c ...
- hdu1233 还是畅通工程 基础最小生成树
//克鲁斯卡尔 #include<iostream> #include<algorithm> using namespace std; ; struct node { int ...
- Selenium | 网上教程
java selenium (一) selenium 介绍 java selenium (二) 环境搭建方法一 java selenium (三) 环境搭建 基于Maven java selenium ...
- bzoj 4909 [Sdoi2017]龙与地下城
题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4909 题解 目前为止仅仅在LOJ上A掉这道题(Loj真快!) 当然不是标准做法 显然我们只要 ...
- 优先队列 HDOJ 5437 Alisha's Party
题目传送门 题意:一人过生日,很多人排着队送礼物.排队顺序是礼物价值大的优先,如果相等先来的优先.有m次开门,当t个人到了会开门让p个人进门.最后一次让门外的所有人按顺序进门.有q次询问,问第x个进门 ...
- OGG How to Resync Tables / Schemas on Different SCN s in a Single Replicat
To resync one or more tables/schemas on different SCN's using a single or minimum number of replicat ...