Tomcat DIGEST 摘要验证

DIGEST 消息摘要验证也是 Tomcat 的自带验证方式,与 BASIC 认证的设置基本一致。先在 conf/server.xml 中添加Realm 领域数据源,然后在 web.xml 中添加 <security-constraint> 和 <login-config> 元素。

两者的唯一区别是 web.xml 配置时,<auth-method> 元素指定的认证方法,基本认证设置 <auth-method> 为 BASIC,而摘要认证设置 <auth-method> 为 DIGEST。

示例

创建 Web 项目

可以使用 IDEA、Eclipse 等工具创建一个 Web 项目(当然也可以手动创建),项目的的结构如下图:

其中,index.jsp 页面为 Web 应用的主页面,需要用户登录授权后才能访问。而 web.xml 是 Web 应用的配置文件。

添加 index.jsp 页面

index.jsp 页面内容如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta charset="UTF-8">
    <title>DEMO</title>
</head>
<body>
    <h1>DIGEST 摘要验证</h1>
</body>
</html>

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>
    <display-name>Archetype Created Web Application</display-name>

    <security-constraint>
        <display-name>default</display-name>
        <!-- 需要限制访问的资源子集 -->
        <web-resource-collection>
            <web-resource-name>all files</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <!-- 指定可以访问该资源集合的用户角色,这里指定为 JAAS 中的角色 -->
        <auth-constraint>
            <role-name>manager-gui</role-name>
        </auth-constraint>
        <!-- 用来显示怎样保护在客户端和Web容器之间传递的数据 -->
        <!-- NONE 不需要传输保证 -->
        <!-- INTEGRAL 服务器和客户端之间的数据必须以某种方式发送,而且在传送中不能改变 -->
        <!-- CONFIDENTIAL 传输的数据必须是加密的数据 -->
        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <!-- 配置登录方式为 digest 摘要验证方式 -->
    <login-config>
        <!-- 指定验证方式 -->
        <auth-method>DIGEST</auth-method>
        <!-- 指定领域名称,必须和生成摘要密码中的领域名称一致 -->
        <realm-name>myRealm</realm-name>
    </login-config>

    <security-role>
        <role-name>manager-gui</role-name>
    </security-role>

</web-app>

生成用户密码

接下来,需要生成 Tomcat 可识别的 MD5 摘要密码。生成密码有两种方式,正如官网描述:

To calculate the digested value of a cleartext password, two convenience techniques are supported:

为了计算明文密码的摘要值,支持两种便捷技术:

(1)If you are writing an application that needs to calculate digested passwords dynamically, call the static Digest() method of the org.apache.catalina.realm.RealmBase class, passing the cleartext password and the digest algorithm name as arguments. This method will return the digested password.

如果您正在编写一个需要动态计算摘要密码的应用程序,请调用 org.apache.catalina.realm.RealmBase 类的静态 Digest() 方法,将明文密码和摘要算法名称作为参数传递,此方法将返回摘要密码。例如:

import org.apache.catalina.realm.RealmBase;

/**
 * Tomcat MD5 摘要密码生成器
 * @author hxstrive.com 2022/6/16
 */
public class DigestPwdGenerator {

    public static void main(String[] args) {
        String digest = RealmBase.Digest(
                "tomcat:myRealm:aaaaaa", "MD5", "UTF-8");
        System.out.println(digest);
    }

}

注意,上面 DEMO 需要添加 %CATALINA_HOME%/lib/*.jar 和 %CATALINA_HOME%/bin/tomcat-juli.jar 依赖。运行 DEMO 输出加密后的摘要如下:

000edf117940faf92f394f14c15752b6

(2)If you want to execute a command line utility to calculate the digested password, simply execute

如果要执行命令行实用程序来计算摘要密码,只需执行

CATALINA_HOME/bin/digest.[bat|sh] -a {algorithm} {cleartext-password}

and the digested version of this cleartext password will be returned to standard output.

并且此明文密码的摘要版本将返回到标准输出。在 Windows 下,示例如下:

D:apache-tomcat-7.0.64-2in> digest.bat -a MD5 tomcat:myRealm:aaaaaa

tomcat:myRealm:aaaaaa:000edf117940faf92f394f14c15752b6

cleartext-password 的格式?

官方是这样描述的:

If using digested passwords with DIGEST authentication, the cleartext used to generate the digest is different and the digest must use the MD5 algorithm. In the examples above {cleartext-password}must be replaced with {username}:{realm}:{cleartext-password} . For example, in a development environment this might take the form  testUser:Authentication required:testPassword . The value for  {realm} is taken from the  <realm-name> element of the web application’s  <login-config> . If not specified in web.xml, the default value of  Authentication required is used.

如果将摘要密码与摘要身份验证一起使用,则用于生成摘要的明文不同,摘要必须使用 MD5 算法。在上面的示例中,必须用 {用户名}:{领域}:{清除文本-密码} 替换 {clartext-password}。例如,在开发环境中,这可能采用以下形式:tomcat:myRealm:aaaaaa

从 Web 应用程序的 <LOGIN-CONFIG> 的 <Realm-Name> 元素中获取 {领域} 的值。如果未在 web.xml 中指定,则使用缺省值所需的身份验证。

配置用户密码

打开 tomcat 的 tomcat-users.xml 配置文件,将用户的明文密码替换成上面生成的摘要密码。如下:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
    <role rolename="manager-gui"/>
    <role rolename="manager-script"/>
    <role rolename="manager-jmx"/>
    <role rolename="manager-status"/>
    <role rolename="admin-gui"/>
    <user username="tomcat" password="000edf117940faf92f394f14c15752b6"
        roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui"/>
</tomcat-users>

部署 Web 应用

将该 Web 应用打包成 war 包的方式去部署运行 Web 应用,或者直接通过 IDEA 内置 Tomcat 功能运行该 Web 应用。

运行成功后,使用浏览器访问项目 index.jsp 页面。如下图:

输入用户名和密码点击“登录”按钮进行登录,如果密码验证通过,则跳转到主页。如下图:

通过浏览器调试工具,可以看到 Authorization 请求头字段信息如下:

Authorization: Digest username="tomcat", realm="myRealm", nonce="1655442073849:9d39b54c1ecf010670262e92aeed1705", uri="/tomcat_auth_digest/", response="0128f8cedaabe9c1ec85fed4efb45b5d", opaque="D4766067E4D56D43888D83EDAB07A0BE", qop=auth, nc=00000002, cnonce="753daa8372c48293"

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号