认证授权包含2个方面:
(1)访问某个资源时必须携带用户身份信息,如:用户登录时返回用户access_token,访问资源时携带该参数。
(2)检查用户是否具备访问当前资源(url或数据)的权限:访问资源时检查用户权限。

在REST架构中,access_token被定义为用户身份标识,用于对资源访问授权,只允许系统合法用户访问资源。具体来说:
 - 必须在每次访问时都携带access_token参数,参数位置可以位于HTTP消息头(HTTP Basic Authentication),也可放在请求参数列表中。
 - 如果在访问请求中不存在access_token参数,或者验证access_token不合法(不存在或者不正确),拒绝访问,必须强制用户登录。

如何生成安全有效的用户access_token?
acces_token作为用户身份标识,必然与数据库中的用户一一对应,即:<access_token : user_id>。
在网络通信中,一切数据都是透明的,都能被抓包截获,所以必须保证access_token具备如下特性:
1. access_token需要满足分布式环境下的全局唯一性
2. access_token中不应该包含用户信息,如果将用户id编码到access_token中很容易泄露系统用户信息(通常用户id都是自增长的,很容易曝露系统当前用户规模等信息)。
3. access_token应该是动态变化的,即:用户每次登录时得到的access_token值都与上一次登录不同。这样保证参数没有规律性,避免被用于网络攻击。
4. access_token应该具备一定特征,用于参数合法性验证,如:长度必须满足30个字符。

参照如上需求,可以按照如下方式设计access_token:
(1)用户登录时,动态生成UUID作为该用户的access_token,同时以access_token为key,用户id为value存入redis。
(2)用户访问资源时携带access_token,解析验证请求参数。
(3)如果access_token在redis中不存在,则说明用户还未登录,强制用户登录;转到(1)。
(4)如果access_token不合法(如字符长度不满足),强制用户重新登录;转到(1)。
(5)验证access_token通过,继续其他权限验证或者资源访问。

此外,根据业务场景可以作如下约定以增强access_token安全性:
1. 设置access_token超时时间,即:超过一定时间之后就必须让access_token失效,强制用户重新登录。
2. 使用HTTP Basic Authentication,将access_token放在http消息头中而不是直接放在请求参数里,这样做更加规范。
3. 由于UUID会使用时间戳,所以需要对集群内服务器进行时钟同步

注意:
JDK提供的默认UUID实现是基于名字空间的UUID(UUID Version 3)和基于伪随机数的UUID(UUID Version 4),很难保证在分布式环境下是全局唯一的。一个可选的开源Java UUID实现组件:
https://github.com/cowtowncoder/java-uuid-generator Java Uuid Generator (JUG),提供基于时间和MAC地址的UUID Version 1实现

当然,如果在实际的业务系统中能保证名称唯一,比如用户手机或者邮箱,那么可以直接使用JDK基于名称空间的UUID V3实现。

之所以选择UUID作为access_token实现,基于如下考虑:
(1)性能:UUID生成在本地完成,高效。
(2)简单有效:只要保证access_token全局唯一即可,且可以动态变化。

实际上,实现认证最优雅的方式应该是使用JWT,这是一个Token标准。

【参考】
https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E5%94%AF%E4%B8%80%E8%AF%86%E5%88%AB%E7%A0%81 UUID
https://www.zhihu.com/question/34876910 UUID是如何保证唯一性的?
http://blog.csdn.net/fengshizty/article/details/48754609 App开放接口api安全性—Token签名sign的设计与实现
http://www.cnblogs.com/QLeelulu/archive/2009/11/22/1607898.html 访问需要HTTP Basic Authentication认证的资源的各种语言的实现
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization
https://zxc0328.github.io/2015/11/04/http-basic-auth/ Http Basic Authorization的使用

细说REST API安全之认证授权的更多相关文章

  1. Yii2 restful api创建,认证授权以及速率控制

    Yii2 restful api创建,认证授权以及速率控制 下面是对restful从创建到速率控制的一个详细流程介绍,里面的步骤以及截图尽可能详细,熟悉restful的盆友可能觉得过于繁琐,新手不妨耐 ...

  2. IdentityServer4[3]:使用客户端认证控制API访问(客户端授权模式)

    使用客户端认证控制API访问(客户端授权模式) 场景描述 使用IdentityServer保护API的最基本场景. 我们定义一个API和要访问API的客户端.客户端从IdentityServer请求A ...

  3. [认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)

    0 目录 认证授权系列:http://www.cnblogs.com/linianhui/category/929878.html 1 什么是OIDC? 看一下官方的介绍(http://openid. ...

  4. [认证授权] 4.OIDC(OpenId Connect)身份认证(核心部分)

    1 什么是OIDC? 看一下官方的介绍(http://openid.net/connect/): OpenID Connect 1.0 is a simple identity layer on to ...

  5. 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...

  6. 细说ASP.NET Forms身份认证

    阅读目录 开始 ASP.NET身份认证基础 ASP.NET身份认证过程 如何实现登录与注销 保护受限制的页面 登录页不能正常显示的问题 认识Forms身份认证 理解Forms身份认证 实现自定义的身份 ...

  7. Owin中间件搭建OAuth2.0认证授权服务体会

    继两篇转载的Owin搭建OAuth 2.0的文章,使用Owin中间件搭建OAuth2.0认证授权服务器和理解OAuth 2.0之后,我想把最近整理的资料做一下总结. 前两篇主要是介绍概念和一个基本的D ...

  8. 使用Owin中间件搭建OAuth2.0认证授权服务器

    前言 这里主要总结下本人最近半个月关于搭建OAuth2.0服务器工作的经验.至于为何需要OAuth2.0.为何是Owin.什么是Owin等问题,不再赘述.我假定读者是使用Asp.Net,并需要搭建OA ...

  9. 在AngularJS应用中实现认证授权

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAokAAAFwCAIAAABbwHY6AAAgAElEQVR4nOy9+XtcxbX3+/4H9z73jP ...

随机推荐

  1. Hdoj 4508.湫湫系列故事——减肥记I 题解

    Problem Description 对于吃货来说,过年最幸福的事就是吃了,没有之一! 但是对于女生来说,卡路里(热量)是天敌啊! 资深美女湫湫深谙"胖来如山倒,胖去如抽丝"的道 ...

  2. Leetcode 27.移除元素 By Python

    给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ...

  3. HGOI 20190310 题解

    /* 又是又双叒叕WA的一天... 我太弱鸡了... 今天上午打了4道CF */ Problem 1 meaning 给出q组询问,求下列函数的值$ f(a) = \max\limits_{0 < ...

  4. MongoDB 数据库创建删除、表创建删除、数据增删改查

    一.管理 mongodb 数据库:mongo 查看所有数据库列 表 show dbs 二. 创建数据库 创建 数据库 use student 如果真的想把这个数据库创建成功,(collections) ...

  5. 一个ArrayList在循环过程中删除,会不会出问题,为什么?

    ArrayList中的remove方法(注意ArrayList中的remove有两个同名方法,只是入参不同,这里看的是入参为Object的remove方法)是怎么实现的: public boolean ...

  6. Java 对远程文件的操作

    首先添加jar <dependency> <groupId>jcifs</groupId> <artifactId>jcifs</artifact ...

  7. 第二十三篇-ubuntu18.04怎么下载播放器以及如何设置默认播放器

    下载播放器 安装命令:sudo apt-get install smplayer再安装解码器: 安装win32codecs包 如果是intel的CPU 代码: sudo apt-get install ...

  8. Codeforces Round #525 (Div. 2) C. Ehab and a 2-operation task

    传送门 https://www.cnblogs.com/violet-acmer/p/10068786.html 题意: 给定一个长度为 n 的数组a[ ],并且有两种操作: ①将前 i 个数全都加上 ...

  9. 高级组件——表格JTable

    JTable(Object[][] rowData,Object[] columnNames)                         表格数据              列名集合 setSe ...

  10. java中异常的面试

    https://blog.csdn.net/qq_36523638/article/details/79363652 1) Java中的检查型异常和非检查型异常有什么区别? 这又是一个非常流行的Jav ...