srverlet Container或web应用程序自己均可以提供控制web应用程序资源的安全防御html
前者称为容器管理的安全防御,或者称为应用程序管理安全防御java
经过内嵌机制,tomcat提供一些安全防御方法,这是一种“容器管理”的安全防御。另外一方面若是有一系列具备本身的登陆机制的servlet和JSP,则视为应用程序管理的安全防御。web
无论是哪一种安全防御类型,都是用称之为领域(realm)的组来管理用户和密码。算法
下面将介绍conf/server.conf中领域的配置(定义了如何存储用户与角色信息),以及web应用程序的WEB_INF/web.xml中的<security-constraint>(如何对webapp的用户进行受权)sql
1、领域的配置数据库
Tomcat含有可插入式的领域架构,且具有多种有用的领域实现:apache
Java开发者可建立额外的领域实现,以便做为与其用户和密码的接口。如欲指定使用何种领域,在server.conf配置文件中插入Realm元素,以className属性设定要使用的领域,而后经过 该实现的自定义属性以提供此领域相关的配置信息:浏览器
<Realm className="SOME.REALM.IMPLEMENTATION.CLASSNAME"
CUSTOMATRRIBUTION1="SOME CUSTOM VALUE"
CUSTOMATTRIBUTION2="SOME OTHER CUSTOM VALUE"/>tomcat
后面的realm配置能够覆盖前面安全
每种不一样的Realm 采用了不一样的用户名和密码存储和使用方式,tomcat默认使用的是UserDatabaseRealm。
一、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/>元素中,则只有对应的应用程序能被访问
二、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/>元素中,则只有对应的应用程序能被访问
三、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表达式,则会忽略此属性
四、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[2]; callbacks[0] = new NameCallback("user name"); callbacks[1] = 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[0]; PasswordCallback passwordCallback = (PasswordCallback) callbacks[1]; username = nameCallback.getName(); char[] tmpPassword = passwordCallback.getPassword(); passwordCallback.clearPassword();// clean password in memory space if (tmpPassword == null) { tmpPassword = new char[0];// treat a NULL password as an empty password } password = new char[tmpPassword.length]; System.arraycopy(tmpPassword, 0, password, 0, 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 = 0; 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 不进去。
五、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>
六、MemoryRealm
这个是最简单的配置,默认是读取tomcat-users.xml(可经过pathname属性配置为其它文件)里面配置的用户角色信息。
修改server.xml 添加配置:
<Realm className="org.apache.catalina.realm.MemoryRealm"/>
七、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"/>
八、LockOutRealm
它继承于CombinedRealm,和CombinedRealm同样,与它一块儿工做的Realm须要嵌套在LockOutRealm中,并且也是只须要知足任何一个Realm便可。若是在必定的时间内屡次尝试受权失败,它将会锁定这个用户。使用它时,不须要修改它下面的Realm配置,由于它是经过记录全部失败的登陆(包括不存在的用户)来实现的。
2、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(证书认证)
一、BASIC(基础认证):须要提供base64编码文本的用户口令,这种验证方法,全部的密码都会以base64编码文本在网络上传递
示例以下:
二、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文件中做为某个用户的密码
示例以下:

三、FROM(表单认证):在网页的表单上要求提供用户密码
当用户请求web应用程序受保护的资源时,表单验证会显示登陆表单的网页画面,在web应用程序中,为实现表单验证,须要登陆表单的网页与验证失败的错误信息网页
示例:
/login.html,form-login-page元素表示当tomcat发现未登陆的用户企图访问受到security-constraint保护保护的资源时,须要显示给用户的网页
/error.html,form-error-page元素表示当用户登陆失败时,tomcat要显示给用户的网页
四、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、角色声明
必需明出全部用到的角色