博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HTTP确认访问用户身份的认证
阅读量:3957 次
发布时间:2019-05-24

本文共 5043 字,大约阅读时间需要 16 分钟。

你未必出类拔萃,但一定与众不同

HTTP确认访问用户身份的认证

HTTP确认访问用户身份的认证

  • BASIC认证
  • DIGEST认证
  • SSL客户端认证
  • FormBase认证

1.BASIC认证

概述

BASIC认证是从HTTP1.0就定义的一种WEB服务器与通信客户端之间进行的认证方式,又称为基本认证

认证步骤

在这里插入图片描述

  • 当请求的资源需要进行BASIC认证时,服务器会随状态码401Authorization Required,返回带WWW-Authorization首部字段的响应,该字段内包含认证的方式以及Request-URI安全域字符串
  • 接受到状态码401的客户端为了通过BASIC认证,需要将ID和密码发送给服务器,发送的内容是ID:密码然后通过Base64编码处理
  • 接受到包含首部字段的Authorization请求的服务器,会对认证信息的正确性进行验证,验证通过则返回一条包含Request-URI资源的响应

下图就是对接受到的Authorization字段进行处理,只不过Authorization中存储的是当前请求生成的SessonId进行校验

public class MySessionManager extends DefaultWebSessionManager {    /**     * 日志记录     */    private final Logger logger =  LoggerFactory.getLogger(this.getClass());    private static final String AUTHORIZATION = "Authorization";    private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";    public MySessionManager() {        super();    }    @Override    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {        String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);        //如果请求头中有 Authorization 则其值为sessionId        if (!StringUtils.isEmpty(id)) {            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);            return id;        } else {            //否则按默认规则从cookie取sessionId            return super.getSessionId(request, response);        }    }}

缺点

  • 虽然采用Base64进行处理,但是不是加密处理,不需要附加信息进行解密
  • 无法实现认证注销操作
  • 认证使用上不够灵活

2.DIGEST认证

概述

为了弥补BASIC认证的缺点,HTTP在1.1开始就有了DIGEST认证

DIGEST认证同样采用质询/相应的方式,但是不会像BASIC认证认证一样发送明文

质询方式

一开始一方会先发送认证要求给另一方,接着使用从另一方那接受到的质询码计算生成响应码,最后返回响应码的认证方式。

发送给对方的只是响应摘要以及质询码产生的计算结果,比起BASIC认证,密码泄露的可能性降低了

认证步骤

在这里插入图片描述

  • 请求需要认证的资源,服务器会随状态码401Authorization Required,返回带WWW-Authorization首部字段的响应,该字段包含质问响应方式认证所需的临时质询码(随机数)

    首部字段WWW-Authorization内必须包含realm和nonce这两个字段的信息,客户端就是依靠向服务器回送这两个值进行认证

  • 接受到401状态码的客户端,返回的响应中包含DIGEST认证必须的首部字段Authorization信息

    Authorization必须包含username,realm,nonce,uri,response

  • 接收到包含首部字段Authorization请求的服务器,会先确认认证信息的正确性,认证通过后则返回包含Reques-URI资源的响应。

缺点

  • 不存在防止用户伪装的保护机制
  • 安全等级比不上HTTPS的客户端认证

3.SSL客户端认证

SSL客户端认证借由HTTPS 的客户端认证起效

HTTPS的认证过程看这篇

认证步骤

  • 接受到需要认证资源的请求,服务器会发送Certificate Request报文,要求客户端提供客户端证书
  • 用户选择将发送的客户端证书后,客户端会把客户端证书信息以Client Certificate报文方式发送给服务器。
  • 服务器验证客户端证书验证通过之后方可领取证书内容客户端的公开秘钥,然后开始HTTPS加密通信

SSL客户端一般采用双因素认证

  • SSL客户端证书用来认证客户端计算机
  • 密码用来确认用户的行为

缺点

  • 证书需要付费,耗费较大

4.FormBase认证

基于表单认证,目前市面上大多数都是基于表单认证。

认证过程

在这里插入图片描述

  • 客户端把一些用户信息登录信息放入报文的实体部分,通常使用POST方式,然后使用HTTPS通信来进行表单画面的显示以及用户输入的方式
  • 服务器会发放用以识别用户的SessionId 通过验证从客户端发送过来的登录信息进行身份认证,然后把用户的认证状态与SessionId绑定后记录在服务器端
  • 客户端接收到SessionId 将其视为Cookie保存在本地,下次发送请求的时候,在带入Cookie

实践应用

微信小程序发送请求的时候可能不会带入cookie,因此采用表单认证,我们自定义创建一个表单认证

小程序js Authorization存储的就是当前的sessionId,不过这个是我们返回的

// post请求封装export function postRequest(url, data) {	var promise = new Promise((resolve, reject) => {		var that = this;		var postData = data;		uni.request({			url: commonUrl + url,			data: postData,			method: "POST",			header: {				"content-type": "application/x-www-form-urlencoded",				Authorization: uni.getStorageSync("sessionId")			},			success: function(res) {				//返回什么就相应的做调整				if (res.statusCode == 200) {					resolve(res.data);				} else {					// 请求服务器成功,但是由于服务器没有数据返回,此时无code。会导致这个空数据					//接口后面的then执行					// 不下去,导致报错,所以还是要resolve下,这样起码有个返回值,					//不会被阻断在那里执行不下去!					resolve(res.data.msg);				}			},			error: function(e) {				reject("网络出错");			}		});	});	return promise;}

后端SpringBoot 采用shiro进行校验认证

自定义一个Session管理器,用来对小程序发送的前端Header中的sessionId进行取值

public class MySessionManager extends DefaultWebSessionManager {    /**     * 日志记录     */    private final Logger logger =  LoggerFactory.getLogger(this.getClass());    private static final String AUTHORIZATION = "Authorization";    private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";    public MySessionManager() {        super();    }    @Override    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {        String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);        //如果请求头中有 Authorization 则其值为sessionId        if (!StringUtils.isEmpty(id)) {            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);            return id;        } else {            //否则按默认规则从cookie取sessionId            return super.getSessionId(request, response);        }    }}

在进行第一次登陆的时候

HttpSession session = request.getSession();String sessionId = session.getId();................登陆业务成功以后,返回一个我们生成的sessionIdresultMap.setSessionId(sessionId);

resultMap是我们自定义的一个返回标准类

然后将我们定义的sessionManager注册进去shiro

/** * 自定义sessionManager * @return */@Beanpublic SessionManager sessionManager() {    MySessionManager mySessionManager = new MySessionManager();    return mySessionManager;}

转载地址:http://vftzi.baihongyu.com/

你可能感兴趣的文章
hibernate inverse 和cascade讲解
查看>>
建模工具Rose的学习
查看>>
javascript ajax提出异步请求
查看>>
Hibernate 中的 QBC
查看>>
解快局域网共享问题
查看>>
xp常用命令
查看>>
java 加密解密
查看>>
xp 忘记密码
查看>>
xp 忘记密码
查看>>
java 过滤器
查看>>
java 过滤器
查看>>
as发送邮件
查看>>
AJAX应用之注册用户即时检测
查看>>
File 类小结
查看>>
java除去字符串空格
查看>>
jsp 2.0标记文件
查看>>
Hibernate中Criteria的完整用法
查看>>
sql jsp
查看>>
Word生成目录
查看>>
JSP彩色验证码源程序编写
查看>>