深入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());

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值