深入tomcat验证机制

背景

<<Head First Servlets & JSP>>安全一章介绍了tomcat内建的验证机制.

首先介绍术语realm.

As far as theservlet

spec is concerned, arealm is a place where authentication information is stored. When you’retesting your application in Tomcat, you can use a file called“tomcat-users.xml” (located in

tomcat’sconf/directory, NOT within webapps). That one “tomcat-users.xml” file appliesto ALL

applicationsdeployed under web-apps. It’s commonly known as the
memory realm because Tomcat reads this file into memory at startuptime. While it’s great for testing, it’s not recommended for production. Forone thing you can’t modify its contents without restarting Tomcat.

The tomcat-users.xml file

用户名,密码以及角色存储于/conf/tomcat-users.xml文件.这里不详细介绍.

<rolerolename="Admin"/>

<rolerolename="Member"/>

<rolerolename="Guest"/>

<userusername="Annie" password="admin"roles="Admin,Member,Guest" />

<userusername="Diane" password="coder"roles="Member,Guest" />

<userusername="Ted" password="newbie" roles="Guest"/>

Tomcat厂商指定角色映射

<security-role><role-name>Admin</role-name></security-role>

<security-role><role-name>Member</role-name></security-role>

<security-role><role-name>Guest</role-name></security-role>

Enabling authentication

web.xml文件

<login-config>

<auth-method>BASIC</auth-method>

</login-config>

注意:验证方法包括BASIC,DIGEST,CLIENT-CERT以及FORM.表单验证时,action填写j_security_check,用户名name填写j_username,密码name填写j_password,即能自动使用tomcat-users文件中的数据验证.

Defining resource/method constraints

<security-constraint>element in the DD.

<security-constraint>

<web-resource-collection>

<web-resource-name>newconference</web-resource-name>

<url-pattern>/createConference</url-pattern>

<url-pattern>/createConference.do</url-pattern>

<http-method>GET</http-method>

<http-method>POST</http-method>

</web-resource-collection>

<web-resource-collection>

<web-resource-name>newschedule</web-resource-name>

<url-pattern>/newSchedule</url-pattern>

<http-method>GET</http-method>

<http-method>POST</http-method>

</web-resource-collection>

<web-resource-collection>

<web-resource-name>accountmanagement</web-resource-name>

<url-pattern>/editPassword</url-pattern>

<url-pattern>/editPassword.do</url-pattern>

<http-method>GET</http-method>

<http-method>POST</http-method>

</web-resource-collection>

<auth-constraint>

<role-name>Admin</role-name>

</auth-constraint>

<!--

<user-data-constraint>

<transport-guarantee>CONFIDENTIAL</transport-guarantee>

</user-data-constraint>

-->

</security-constraint>

当你访问安全约束中指定的页面时,就会弹出或跳转至登录页面,用户登录之后并满足指定角色才能访问页面.使用很简单,那么tomcat验证机制是如何实现的呢?tomcat验证机制能满足我们实际所需吗?参考Apache
Tomcat文档以及Apache Tomcat源代码.

tomcat验证机制如何实现

Configuration a Realm

参考Apache Tomcat
官方文档Realm Configuration HOW-TO.

In general, you willbe adding an XML element to your conf/server.xml configuration file, that lookssomething like this:

<!-- ThisRealm uses the UserDatabase configured in the global JNDI

resources under the key"UserDatabase".  Any edits

that are performed against thisUserDatabase are immediately

available for use by the Realm.  -->

<RealmclassName="org.apache.catalina.realm.UserDatabaseRealm"

resourceName="UserDatabase"/>

这儿配置UserDatabaseRealm.接下来看看UserDatabase资源配置

<!-- Global JNDI resources

Documentation at/docs/jndi-resources-howto.html

-->

<GlobalNamingResources>

<!-- Editable user database that canalso be used by

UserDatabaseRealm to authenticateusers

-->

<Resource name="UserDatabase"auth="Container"

type="org.apache.catalina.UserDatabase"

description="User databasethat can be updated and saved"

factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

pathname="conf/tomcat-users.xml" />

</GlobalNamingResources>

配置中涉及到org.apache.catalina.realm.UserDatabaseRealm,org.apache.catalina.UserDatabase,org.apache.catalina.users.MemoryUserDatabaseFactory这三个类,应该是用于实现tomcat验证机制.

查阅JavaDoc相关类.

UserDatabaseRealm有个成员

/**

* The<code>UserDatabase</code> we will use to authenticate users

* and identify associated roles.

*/

UserDatabase
database;

MemoryUserDatabaseFactory

Createand return a new MemoryUserDatabase instancethat has been configured according to
the properties of the specified Reference. If you instance can be created, return nullinstead.

MemoryUserDatabase

Concreteimplementation of UserDatabase that loads all defined users, groups, and rolesinto an in-memory data structure, and uses a specified XML file for itspersistent storage.

至于相关的各种验证方法见包org.apache.catalina.authenticator,比如表单验证方法即FormAuthenticator.

public booleanauthenticate(Request request,

Responseresponse,

LoginConfigconfig)

代码块

Realm realm =context.getRealm();

if (characterEncoding != null) {

request.setCharacterEncoding(characterEncoding);

}

String username =request.getParameter(Constants.FORM_USERNAME);

String password =request.getParameter(Constants.FORM_PASSWORD);

if (log.isDebugEnabled())

log.debug("Authenticatingusername ‘" + username + "‘");

principal =realm.authenticate(username, password);

if (principal == null) {

//用户名或密码错误

forwardToErrorPage(request,response, config);

return (false);

}

RealmBase

/**

* Return the Principal associated with thespecified username and

* credentials, if there is one; otherwisereturn <code>null</code>.

*

* @param username Username of thePrincipal to look up

* @param credentials Password or othercredentials to use in

* authenticating this username

*/

public Principal authenticate(Stringusername, String credentials) {

String serverCredentials =getPassword(username);

boolean validated ;

if ( serverCredentials == null ) {

validated = false;

} else if(hasMessageDigest()) {

validated =serverCredentials.equalsIgnoreCase(digest(credentials));

} else {

validated =serverCredentials.equals(credentials);

}

if(! validated ) {

if (containerLog.isTraceEnabled()){

containerLog.trace(sm.getString("realmBase.authenticateFailure",

username));

}

return null;

}

if (containerLog.isTraceEnabled()) {

containerLog.trace(sm.getString("realmBase.authenticateSuccess",

username));

}

return getPrincipal(username);

}

tomcat验证机制能满足实际所需吗

使用数据库

以mysql为例.

To set up Tomcat touse JDBCRealm, you will need to follow these steps:

  1. If you have not yet done so, create tables and columns in your database that conform to the requirements described above.
  1. Configure a database username and password for use by Tomcat, that has at least read only access to the tables described above. (Tomcat will never attempt
    to write to these tables.)
  1. Place a copy of the JDBC driver you will be using inside the $CATALINA_HOME/lib directory. Note that only JAR files are recognized!
  1. Set up a <Realm> element, as described below, in your $CATALINA_BASE/conf/server.xml file.
  2. Restart Tomcat if it is already running.

realm配置使用JDBCRealm.

<Resourcename="jdbc/conference" auth="Container"

type="javax.sql.DataSource" username="root"password="root"

driverClassName="com.mysql.jdbc.Driver"url="jdbc:mysql://127.0.0.1:3306/conference?useUnicode=true&amp;characterEncoding=utf8"

maxTotal="8"maxIdle="4" />

<RealmclassName="org.apache.catalina.realm.JDBCRealm"

driverName="org.gjt.mm.mysql.Driver"

connectionURL="jdbc:mysql://127.0.0.1:3306/conference?user=root&amp;password=root"

userTable="users"userNameCol="user_name" userCredCol="user_pass"

userRoleTable="user_roles"roleNameCol="role_name" />

mysql数据库中建表

create table users (

user_name         varchar(15) not null primary key,

user_pass         varchar(15) not null

);

create tableuser_roles (

user_name         varchar(15) not null,

role_name         varchar(15) not null,

primary key (user_name, role_name)

);

jdbc driver for mysql放入tomcatlib目录下

比如当前最新的文件mysql-connector-java-5.1.34-bin.jar.

A typical use of this resource reference might looklike this:

参考Apache tomcat文档JNDI
Resources HOW-TO: JDBC DataSources.

Context initCtx =new InitialContext();

Context envCtx =(Context) initCtx.lookup("java:comp/env");

DataSource ds =(DataSource)

envCtx.lookup("jdbc/conference");

Connection conn =ds.getConnection();

... use thisconnection to access the database ...

conn.close();

获取验证用户角色以及用户名

HttpServletRequest

  • getUserPrincipal
  • getRemoteUser
  • isUserInRole

以获取用户名为例

Principal principal= request.getUserPrincipal();

System.out.println(principal.getName());

时间: 2024-11-14 12:50:53

深入tomcat验证机制的相关文章

Oracle基础学习2--Oracle登录与三种验证机制

首先,Oracle安装完毕有三个默认用户 ?  Sys:数据库对象的拥有者.权限最高.password在安装的时候(口令管理)能够改变 ?  System:数据库管理员,password为manager ?  Scott:一个普通用户,password为tiger 再看连接Oracle的三种验证机制 ?  操作系统验证(具体解释见以下) ?  password文件验证 ?  数据库验证 注:前两者适用于系统用户,比方:Sys.System等:最后一个适用于普通用户.比方:Scott. 再看Ora

定制Asp.NET 5 MVC内建身份验证机制 - 基于自建SQL Server用户/角色数据表的表单身份验证

背景 在需要进行表单认证的Asp.NET 5 MVC项目被创建后,往往需要根据项目的实际需求做一系列的工作对MVC 5内建的身份验证机制(Asp.NET Identity)进行扩展和定制: Asp.NET内建的身份验证机制会使用Local DB(本地数据库)读写用户相关的信息,而在数据库驱动的项目中,管理业务信息的数据库通常是特定的数据库环境,比如远程SQL Server数据库实例或Access数据库等等,业务数据库中保存着一系列针对业务需求的数据表,因此需要定制MVC 5内建身份验证,使其操作

ASP.NET 身份验证机制

ASP.NET提供了3种认证方式:windows身份验证:IIS根据应用程序的设置执行身份验证.要使用这种验证方式,在IIS中必须禁用匿名访问.Forms验证          :用Cookie来保存用户凭证,并将未经身份验证的用户重定向到自定义的登录页.Passport验证      :通过Microsoft的集中身份验证服务执行的,他为成员站点提供单独登录和核心配置文件服务. 关于这三种验证方式的配置,推荐一篇博文:http://www.cnblogs.com/chenqingwei/arc

逆向工程第005篇:跨越CM4验证机制的鸿沟(上)

一.前言 <冠军足球经理>系列作为一款拟真度极高的足球经营类游戏,赢得过无数赞誉,而CM4可以说是这个传奇的起点.但是在游戏安装过程中,当用户输入完序列号之后,程序并不会对用户的输入进行真伪判断,只有等到安装完毕,进入游戏之后,通过游戏是否正常显示才能够得知.而如果遇到用户不小心输入错误的情况,那么只能卸载游戏重新安装,这就会造成很大的麻烦. 为解决这个问题,这次的研究会以两篇文章的篇幅通过两种方式对这个游戏进行逆向分析,一种是采用常见的"爆破"手段,也就是本文所讨论的方法

tornado 学习之 cookie 验证机制详解

本文和大家分享的主要是tornado中cookie 验证机制相关内容,一起来看看吧,希望对大家 学习tornado有所帮助. 处理过程简单来说就是验证密码之后服务器端(tornado) 返回带有  cookie  信息的  Set-Cookie header 给客户端 ,  之后客户端发起请求时会把此  cookie  放入  Cookie header  中发给服务器端. tornado 设置 cookie 首先是对 cookie  的变量进行设置 , Morsel  是含有几个特殊  key

ASP.NET MVC- 数据验证机制

ASP.NET MVC的数据验证机制,比起ASP.NET WEBFORM那种高效很多.下面记录以下两个示例,以便日后方便查阅. 方式一:在Controller里通过AddModelError方法返回错误的验证信息,看一下代码示例: Controller里的,注意看一下,他Add的时候提交是HTTPPOST,并且传参是传一个MODEL进来. public ActionResult Add() { return View(); } [HttpPost] public ActionResult Add

看好你的门-确保验证机制的安全(2)-安全处理敏感信息

首先需要声明,本文纯属一个毫无远见和真才实学的小小开发人员的愚昧见解,仅供用于web系统安全方面的参考. 1. 前提 执行安全的验证机制,不仅仅要同时满足几个关键安全目标,许多的时候也需要牺牲其他目标.比如易用性.成本.还有功能. 我们需要综合考虑下面这些因素: 系统所提供功能的安全程度: 用户对不同类型的验证控制的容忍和接受程度: 支持一个不够友好的界面需要的整体成本(便捷和安全往往是一个事物的两个方向) 系统所保护的信息或者资产的价值. 2. 安全处理敏感信息 一些基本要求,写下来,以后也可

看好你的门-确保验证机制的安全(3)-正确处理验证信息

首先需要声明,本文纯属一个毫无远见和真才实学的小小开发人员的愚昧见解,仅供用于web系统安全方面的参考. 1. 前提 执行安全的验证机制,不仅仅要同时满足几个关键安全目标,许多的时候也需要牺牲其他目标.比如易用性.成本.还有功能. 2. 正确处理验证信息的基本要求 一些基本要求,写下来,以后也可以参考. 1. 要确认完整的用户名和密码等信息:也就是说,要区分大小写,不过滤或者修改任何字符,不添加也不截断密码: 2. 应用程序要在处理验证信息的过程中,主动防御无法预料的时间.重要的是,如果系统无法

看好你的门-确保验证机制的安全(5)-防止滥用密码修改和密码找回功能

首先需要声明,本文纯属一个毫无远见和真才实学的小小开发人员的愚昧见解,仅供用于web系统安全方面的参考. 1. 前提 执行安全的验证机制,不仅仅要同时满足几个关键安全目标,许多的时候也需要牺牲其他目标.比如易用性.成本.还有功能. 2. 防止滥用密码修改的基本要求 一些基本要求,写下来,以后也可以参考. 1. 加一个简单图片验证码,基本确保是人在操作,而不是机器: 2. 只能从已经通过验证的会话中访问该功能: 3. 不要以任何方式直接提供用户名,也不要使用隐藏表单字段或者cookie提供用户名: