Tomcat容器管理安全的几种验证方式

当访问服务器中受保护的资源时,容器管理的验证方法能够控制确认用户身份的方式。Tomcat支持四种容器管理的安全防御,它们是:html

  • BASIC(基本验证):经过HTTP验证,须要提供base64编码文本的用户口令
  • DIGEST(摘要验证):经过HTTP验证,须要提供摘要编码字符串的用户口令
  • FORM(表单验证):在网页的表单上要求提供密码
  • CLIENT-CERT(客户端证书验证):以客户端证书来确认用户的身份

 基本验证

当web.xml文件中的auth-method元素设置为BASIC时,代表应用使用的是基本验证,每次浏览器请求受保护的Web应用资源时,Tomcat都会使用HTTP基本验证向浏览器索取用户名和密码(以页面弹窗的方式)。使用这种验证方法,全部的密码都会以base64编码的文本在网络上传输。web

先看下项目结构(我用Maven管理的依赖):算法

其中,protect/protect.jsp是被保护的,须要受权访问。apache

说明:本文提到的tomcat-users.xml,server.xml等文件,若是是在Eclipse中启动tomcat,则这些文件在Eclipse中的Servers工程下对应的tomcat下,如图:浏览器

本文提到的web.xml是指项目本身的web.xml,而非Servers项目下Tomcat中的web.xmltomcat

web.xml安全

<security-constraint>
	<web-resource-collection>
		<http-method>GET</http-method>
		<web-resource-name>tomcat protect page</web-resource-name>
		<!-- /protect目录下的全部资源是受保护的 -->
		<url-pattern>/protect/*</url-pattern>
	</web-resource-collection>
	<auth-constraint>
		<!-- 这里的member要与tomcat-user.xml中配置的role一致 -->
		<role-name>member</role-name>
	</auth-constraint>
</security-constraint>
<login-config>
	<!-- 验证方式,可选的值为: "BASIC", "DIGEST", "FORM", "CLIENT-CERT" -->
	<auth-method>BASIC</auth-method>
	<!-- 使用的Realm名字,注意这里不能有空格 -->
	<realm-name>MyConstraints</realm-name>
</login-config>

tomcat-user.xml(注意若是是在Eclipse中启动tomcat,这个tomcat-user.xml在Eclipse中的Servers工程下)服务器

<role rolename="member"/>
<!-- member角色下有一个叫alvis的用户,密码为pwd -->
<user username="alvis" password="pwd" roles="member"/>

重启tomcat后,访问protect目录下的资源,状况是这样的:网络

输入帐户alvis,密码pwd后,访问成功(固然,非protect目录下的资源是能够直接访问的):app

摘要验证

当web.xml文件中的auth-method元素设置为DIGEST时,代表应用使用的是摘要验证。仍是上面的例子,看配置:

web.xml和基本验证同样,只是auth-method修改成DIGEST,此处不赘述。

server.xml中的UserDatabaseRealm(若是tomcat使用的是其余Realm,也同样的)里增长digest属性:

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

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

  • 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.
  • 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.

方式一:用代码来生成:

import org.apache.catalina.realm.RealmBase;

public class T {
	public static void main(String[] args) {
		//参数1:要加密的字符串;参数2:加密算法;参数3:字符串的编码
		String base = RealmBase.Digest("alvis:MyConstraints:pwd", "MD5", null);
		System.out.println(base);
	}
}

因为RealmBase类在catalina.jar包中,若是项目中没有这个类,可在项目上右键-->Java Build Path--> Libraries-->Add Library-->选择Server Runtime-->选择Apache Tomcat V8.0(其实7.0也行),如图:

方式二:用脚原本生成:

在tomcat/bin目录下有个digest.sh(Linux系统)或digest.bat(Windows系统)脚本,运行这个脚本,传入摘要算法和参数便可,这里我在Windows系统上运行,如图:

这里的-a指定摘要算法为MD5,要特别注意这里的参数是:{用户名}:{Realm名}:{密码明文}。用户名就是tomcat-users.xml中配置的<user>名字(这里为alvis),Realm名是在web.xml中配置的<realm-name>(这里为MyConstraints),密码明文即该用户用于登陆的密码(我这里设为pwd)。

只有这样的参数加密后的密码,在tomcat-users.xml中配置才有效,不然是登陆不了的。因为我是参考《Tomcat权威指南(第二版)》的步骤作的,以前试了好久都不知道为何登陆不了,结果在官网找到答案,是这么描述的:

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.

大意是说,若是使用DIGEST方式验证,用于生成摘要的明文必须被替换为这种格式。实践出真知,因此仍是不能彻底看书啊,动手实践才是实在的。

而后就是在tomcat-users.xml中配置生成的密码(经过下方的截图,能够比较password跟上方digest.bat脚本生成的密码是否一致):

以后重启tomcat,效果天然是跟使用基本验证的效果同样了。

表单验证

当web.xml文件中的auth-method元素设置为FORM时,代表应用使用的是表单验证。当用户请求Web应用程序受保护的资源时,表单验证会跳转至配置的登陆页面。当登陆失败时,还须要一个验证失败的页面,仍是上面的例子,看配置:

web.xml

<security-constraint>
	<web-resource-collection>
		<http-method>GET</http-method>
		<web-resource-name>tomcat member part</web-resource-name>
		<url-pattern>/protect/*</url-pattern>
	</web-resource-collection>
	<auth-constraint>
		<role-name>member</role-name>
	</auth-constraint>
</security-constraint>
<login-config>
	<auth-method>FORM</auth-method>
	<realm-name>MyConstraints</realm-name>
	<form-login-config>
		<form-login-page>/form/login.html</form-login-page>
		<form-error-page>/form/error.html</form-error-page>
	</form-login-config>
</login-config>

这里的form/login.html是用于登陆的页面,而form/error.html则是验证失败后跳转到的页面(这两个页面在上方的工程结构图中已经有了)。

login.html

<html>
	<body>
	<h2>Login Page.</h2>
	
	<form method="post" action="j_security_check" name="loginForm">
		<input type="text" name="j_username" /><br>
		<input type="password" name="j_password" /><br>
		<input type="submit" value="Login" />
	</form>
	
	</body>
</html>

注意:这里form的action="j_security_check",帐号的name="j_username"和密码的name="j_password"都是不可变的,不然配置的验证规则不起做用

server.xml中,要去掉Realm中添加的“digest=MD5”这个属性:

tomcat-users.xml中使用明文保存密码:

效果(仅在访问protect目录下的资源时才出现Login Page):

输入错误的帐号和密码,跳转至form/error.html页面:

输入正确的帐号和密码,跳转至受保护的页面:

客户端证书验证

待续

 

Demo下载:

连接: http://pan.baidu.com/s/1gfnqVdT 密码: pubw

参考页面:

https://tomcat.apache.org/tomcat-7.0-doc/realm-howto.html

相关文章
相关标签/搜索