代码示例:https://github.com/ChangMike/servlet-security-test
servlet安全的四个方面
验证,用户名密码方式,证书方式。
授权,已经通过验证的用户的访问级别(访问级别经常被称作角色),如网上商城有公用区,买家区(须登陆)。
保密,敏感数据在互联网上传输时要加密。
数据完整性,数据不能被篡改。
实现方式:声明、代码。
声明后,servlet容器会负责验证和授权的过程。
声明式实现步骤
1、写一个servlet
2、web.xml中,定义验证方式basic、digest、form、client-cert;定义资源被访问的策略。
4、定义用户角色,或在数据库、或在文件。在tomcat的tomcat-users.xml中可定义用户和角色;使用数据库,需要在容器中配置数据库的连接并指定表名列名。
5、在web.xml中引用角色
验证方式
1、basic方式,也叫基本验证,是一种接受用户名和密码的HTTP验证。
访问过程:
浏览器发出对受保护资源的请求;
服务器返回401(未授权)响应,响应中包含一个WWW-Authenticate标头;
浏览器弹出登陆对话框,输入提交,浏览器使用base64编码用户名和密码后将其放到WWW-Authenticate标头发送;
容器从WWW-Authenticate标头中取出信息验证用户身份,授权资源。
接下来每次对服务器访问,都会包含Authenticate标头,服务器每次也会检查此标头,所以登陆有效期会一直持续到关闭浏览器为止。关闭浏览器是结束会话的唯一方式。
2、digest方式,也叫摘要验证。
摘要验证旨在取代基本验证。
basic方式的Base64算法很容易被破解,所以摘要验证使用MD5算法创建用户名、密码的散列发送到服务器。
BASE64是将二进制的字节编码为ASCII序列的编码方式,只要译码就可以取得原本的信息。
3、form方式,页面可以自定义,但数据不加密。
basic、digest方式都有加密功能,但登陆页面不可自定义。
form方式应当结合SSL使用。
form验证原理:
如果要访问受保护的资源,容器会检查用户有没有登陆,方式是查看HttpSession中有没有"javax.security.auth.subject"属性,没有表示没有经过容器验证流程,则转发至登陆网页;
浏览器提交;
如果容器验证成功,容器会在HttpSession中设置属性名称为"javax.security.auth.subject"的实例。
form方式可以通过调用HttpSession的invalidate()方法注销会话。
4、client-cert方式
也使用对话框输入用户名和密码,使用PKC(public key Certificate)作加密,可以保证数据的保密性和完整性。
但客户端需要安装证书,这种方式一般很少用。
SSL协议
SSL协议可以保证传输数据的保密性和完整性。
亚马逊向一个证书颁发商申请了一份证书,而买家使用的浏览器内嵌有前面提到的证书颁发商的公钥。
买家不需要了解SSL原理,也不需要拥有公钥或私钥,他只需要在输入重要资料时,用Https(HTTP over SSL)协议即可。
当买家通过https访问亚马逊时,浏览器和亚马逊服务器间发生了如下事件:
浏览器:你真是亚马逊吗?
亚马逊:是的,这是我的证书。
浏览器:使用证书颁发商的公钥解密亚马逊证书,以验证证书的有效性。
浏览器:光有证书还不够,请再发点别的身份证明给我。
亚马逊:发送消息“我真的是亚马逊”,并产生摘要且用私钥加密之。
浏览器:为接收到的消息产生摘要;使用亚马逊公钥解密收到的摘要;比较。
浏览器:产生一个随机的密钥,使用亚马逊的公钥加密,发送给亚马逊,之后的交流使用对称加密方式。
配置SSL
要使用Https,只要在web.xml中需要安全传输的<security-contraint>中设置:
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
这样,若服务器支持SSL且安装好证书,当你请求受保护的资源时,服务器会要求浏览器重定向使用https。
有一种普遍的误解,认为只有电子商务网站和网上银行必须使用SSL证书。事实上,大多数网站的登陆页面也都应该使用SSL证书。
SSL证书(证书里包含有公钥)
1、生成公私密钥对
2、把公钥发给证书提供商以申请证书,证书提供商核实身份(一般需要我们提供有效身份证明资料)。
3、收到证书,将证书导入密钥存储库。
4、安装密钥存储库到web服务器
——参考《servlet和jsp学习指南》