HTTP 基本认证

HTTP Basic Authentication(HTTP 基本认证)是 HTTP 1.0 提出的一种认证机制,这个想必大家都很熟悉了,我不再赘述。HTTP 基本认证的过程如下: 
客户端发送 HTTP Request 给服务器。

因为 Request 中没有包含 Authorization header,服务器会返回一个 401 Unauthozied 给客户端,并且在 Response 的 Header “WWW-Authenticate” 中添加信息。

客户端把用户名和密码用 BASE64 加密后,放在 Authorization Header 中发送给服务器, 认证成功。

服务器将 Authorization Header 中的用户名密码取出,进行验证, 如果验证通 
过,将根据请求,发送资源给客户端。

基于 Session 的认证

基于 Session 的认证应该是最常用的一种认证机制了。用户登录认证成功后,将用户相关数据存储到 Session 中,单体应用架构中,默认 Session 会存储在应用服务器中,并且将 Session ID 返回到客户端,存储在浏览器的 Cookie 中。

但是在分布式架构下,Session 存放于某个具体的应用服务器中自然就无法满足使用了,简单的可以通过 Session 复制或者 Session 粘制的方案来解决。

Session 复制依赖于应用服务器,需要应用服务器有 Session 复制能力,不过现在大部分应用服务器如 Tomcat、JBoss、WebSphere 等都已经提供了这个能力。

除此之外,Session 复制的一大缺陷在于当节点数比较多时,大量的 Session 数据复制会占用较多网络资源。Session 粘滞是通过负载均衡器,将统一用户的请求都分发到固定的服务器节点上,这样就保证了对某一用户而言,Session 数据始终是正确的。不过这种方案依赖于负载均衡器,并且只能满足水平扩展的集群场景,无法满足应用分割后的分布式场景。

在微服务架构下,每个微服务拆分的粒度会很细,并且不只有用户和微服务打交道,更多还有微服务间的调用。这个时候上述两个方案都无法满足,就要求必须要将 Session 从应用服务器中剥离出来,存放在外部进行集中管理。可以是数据库,也可以是分布式缓存,如 Memchached、Redis 等。这正是 David Borsos 建议的第二种方案,分布式 Session 方案。

基于 Token 的认证

随着 Restful API、微服务的兴起,基于 Token 的认证现在已经越来越普遍。Token 和 Session ID 不同,并非只是一个 key。Token 一般会包含用户的相关信息,通过验证 Token 就可以完成身份校验。像 Twitter、微信、QQ、GitHub 等公有服务的 API 都是基于这种方式进行认证的,一些开发框架如 OpenStack、Kubernetes 内部 API 调用也是基于 Token 的认证。基于 Token 认证的一个典型流程如下:

用户输入登录信息(或者调用 Token 接口,传入用户信息),发送到身份认证服务进行认证(身份认证服务可以和服务端在一起,也可以分离,看微服务拆分情况了)。 
身份验证服务验证登录信息是否正确,返回接口(一般接口中会包含用户基础信息、权限范围、有效时间等信息),客户端存储接口,可以存储在 Session 或者数据库中。 
用户将 Token 放在 HTTP 请求头中,发起相关 API 调用。 
被调用的微服务,验证 Token 权限。 
服务端返回相关资源和数据。

基于 Token 认证的好处如下: 
服务端无状态:Token 机制在服务端不需要存储 session 信息,因为 Token 自身包含了所有用户的相关信息。 
性能较好,因为在验证 Token 时不用再去访问数据库或者远程服务进行权限校验,自然可以提升不少性能。 
支持移动设备。 
支持跨程序调用,Cookie 是不允许垮域访问的,而 Token 则不存在这个问题。

下面会重点介绍两种基于 Token 的认证方案 JWT/Oauth2.0。

三、JWT介绍

JSON Web Token(JWT)是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准(RFC 7519)。来自 JWT RFC 7519 标准化的摘要说明:JSON Web Token 是一种紧凑的,URL 安全的方式,表示要在双方之间传输的声明。JWT 一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 Token 也可直接被用于认证,也可被加密。

JWT 认证流程

客户端调用登录接口(或者获取 token 接口),传入用户名密码。 
服务端请求身份认证中心,确认用户名密码正确。 
服务端创建 JWT,返回给客户端。 
客户端拿到 JWT,进行存储(可以存储在缓存中,也可以存储在数据库中,如果是浏览器,可以存储在 Cookie 中)在后续请求中,在 HTTP 请求头中加上 JWT。 
服务端校验 JWT,校验通过后,返回相关资源和数据。

JWT 结构

JWT 是由三段信息构成的,第一段为头部(Header),第二段为载荷(Payload),第三段为签名(Signature)。每一段内容都是一个 JSON 对象,将每一段 JSON 对象采用 BASE64 编码,将编码后的内容用. 链接一起就构成了 JWT 字符串。如下: 
header.payload.signature

  1. 头部(Header) 
    头部用于描述关于该 JWT 的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个 JSON 对象。

在头部指明了签名算法是 HS256 算法。

  1. 载荷(payload) 
    载荷就是存放有效信息的地方。有效信息包含三个部分:

标准中注册的声明 
公共的声明 
私有的声明

标准中注册的声明(建议但不强制使用): 
iss:JWT 签发者 
sub:JWT 所面向的用户 
aud:接收 JWT 的一方 
exp:JWT 的过期时间,这个过期时间必须要大于签发时间 
nbf:定义在什么时间之前,该 JWT 都是不可用的 
iat:JWT 的签发时间 
jti:JWT 的唯一身份标识,主要用来作为一次性 token, 从而回避重放攻击。

公共的声明 : 
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息. 但不建议添加敏感信息,因为该部分在客户端可解密。

私有的声明 : 
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为 base64 是对称解密的,意味着该部分信息可以归类为明文信息。

示例如下: 

  1. 签名(signature) 
    创建签名需要使用 Base64 编码后的 header 和 payload 以及一个秘钥。将 base64 加密后的 header 和 base64 加密后的 payload 使用. 连接组成的字符串,通过 header 中声明的加密方式进行加盐 secret 组合加密,然后就构成了 jwt 的第三部分。 
    比如:HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)

JWT 的优点: 
跨语言,JSON 的格式保证了跨语言的支撑 
基于 Token,无状态 
占用字节小,便于传输

关于 Token 注销: 
Token 的注销,由于 Token 不存储在服务端,由客户端存储,当用户注销时,Token 的有效时间还没有到,还是有效的。所以如何在用户注销登录时让 Token 注销是一个要关注的点。一般有如下几种方式:

Token 存储在 Cookie 中,这样客户端注销时,自然可以清空掉 
注销时,将 Token 存放到分布式缓存中,每次校验 Token 时区检查下该 Token 是否已注销。不过这样也就失去了快速校验 Token 的优点。 
多采用短期令牌,比如令牌有效期是 20 分钟,这样可以一定程度上降低注销后 Token 可用性的风险。

四、OAuth 2.0 介绍

OAuth 的官网介绍:An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications。OAuth 是一种开放的协议,为桌面程序或者基于 BS 的 web 应用提供了一种简单的,标准的方式去访问需要用户授权的 API 服务。OAUTH 认证授权具有以下特点:

简单:不管是 OAuth 服务提供者还是应用开发者,都很容易于理解与使用; 
安全:没有涉及到用户密钥等信息,更安全更灵活; 
开放:任何服务提供商都可以实现 OAuth,任何软件开发商都可以使用 OAuth;

OAuth 2.0 是 OAuth 协议的下一版本,但不向后兼容 OAuth 1.0,即完全废止了 OAuth 1.0。 OAuth 2.0 关注客户端开发者的简易性。要么通过组织在资源拥有者和 HTTP 服务商之间的被批准的交互动作代表用户,要么允许第三方应用代表用户获得访问的权限。同时为 Web 应用,桌面应用和手机,和起居室设备提供专门的认证流程。2012 年 10 月,OAuth 2.0 协议正式发布为 RFC 6749。

授权流程

OAuth 2.0 的流程如下: 

(A)用户打开客户端以后,客户端要求用户给予授权。(B)用户同意给予客户端授权。(C)客户端使用上一步获得的授权,向认证服务器申请令牌。(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。(E)客户端使用令牌,向资源服务器申请获取资源。(F)资源服务器确认令牌无误,同意向客户端开放资源。

四大角色

由授权流程图中可以看到 OAuth 2.0 有四个角色:客户端、资源拥有者、资源服务器、授权服务器。

客户端:客户端是代表资源所有者对资源服务器发出访问受保护资源请求的应用程序。 
资源拥有者:资源拥有者是对资源具有授权能力的人。 
资源服务器:资源所在的服务器。 
授权服务器:为客户端应用程序提供不同的 Token,可以和资源服务器在统一服务器上,也可以独立出去。

客户端的授权模式

客户端必须得到用户的授权(Authorization Grant),才能获得令牌(access token)。OAuth 2.0 定义了四种授权方式:authorizationcode、implicit、resource owner password credentials、client credentials。

http://geek.csdn.net/news/detail/210756

微服务常见安全认证方案Session token cookie跨域的更多相关文章

  1. 快速理解 session/token/cookie 认证方式

    目录 目录 cookie session token cookie Web Application 一般以 HTTP 协议作为传输协议, 但 HTTP 协议是无状态的. 也就是说 server-sid ...

  2. Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成——部署方案优化

    Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成--部署方案优化 之前我们做的方案部署都是只能选择一个微服务部署并只有一台生产服务器,每个微服务只有一个 ...

  3. thinkphp5.1 cookie跨域、thinkphp5.1 session跨域、tp5.1cookie跨域

    cookie跨域: //config/cookie.php return [ //... //仅7.3.0及以上适用 'samesite' => 'None', //是否加密cookie值,fa ...

  4. 7.【Spring Cloud Alibaba】微服务的用户认证与授权

    有状态 vs 无状态 有状态 那么Session在何时创建呢? 当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServ ...

  5. 微服务统一登陆认证怎么做?JWT ?

    无状态登录原理 1.1.什么是有状态? 有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session. 例如登录:用户登 ...

  6. Spring cloud微服务安全实战-5-12实现基于token的SSO(2)

    我只要把这个meFilter放在AuthorizationFilter后面就可以了. authorizationFilter的排序是3 MeFilter设置为4 就可以了. 拿到了username直接 ...

  7. .NETCore微服务探寻(二) - 认证与授权

    前言 一直以来对于.NETCore微服务相关的技术栈都处于一个浅尝辄止的了解阶段,在现实工作中也对于微服务也一直没有使用的业务环境,所以一直也没有整合过一个完整的基于.NETCore技术栈的微服务项目 ...

  8. SpringCloud微服务常见组件理解

    概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...

  9. 干掉Session?这个跨域认证解决方案真的优雅!

    用户登录认证是 Web 应用中非常常见的一个业务,一般的流程是这样的: 客户端向服务器端发送用户名和密码 服务器端验证通过后,在当前会话(session)中保存相关数据,比如说登录时间.登录 IP 等 ...

随机推荐

  1. noip模拟赛 a

    分析:f(n)就是问有多少对a*b*c = n,如果是Σf(i),那就是问有多少对a*b*c <= n. 这道题和之前做过的一道数三角形的题差不多:传送门,先假设一下a <= b < ...

  2. GMT,UTC,DST,CST时间详解

    全球24个时区的划分       相较于两地时间表,可以显示世界各时区时间和地名的世界时区表(World Time),就显得精密与复杂多了,通常世界时区表的表盘上会标示着全球24个时区的城市名称,但究 ...

  3. hive计算日期差

    首先,hive本身有一个UDF,名字是datediff.我们来看一下这个日期差计算的官方描述,(下面这个是怎么出来的): hive> desc function extended datedif ...

  4. JQuery获取select选中值和清除选中状态(转)

    1.获取值 var provinceSearch = $("#loc_province_search").find("option:selected").att ...

  5. iOS的四种传值方式

    传值有四种方法 : 1. 属性传值 2. 单例传值 3. 代理传值 4. block传值     一.属性传值   (前-->后) 1. 后面的界面定义一个属性  存放前一个界面传过来的值    ...

  6. pg 学习资料

    文/谭峰 DBA,PostgreSQL专家 开源数据库 PostgreSQL 中文资料非常缺乏,很多社区朋友苦于上手的中文资料少,因此汇总收集以下 PostgreSQL 中文资料,包括 Postgre ...

  7. linux下oracle11G DG搭建(二):环绕主库搭建操作

    linux下oracle11G DG搭建(二):环绕主库搭建操作 环境 名称 主库 备库 主机名 bjsrv shsrv 软件版本号 RedHat Enterprise5.5.Oracle 11g 1 ...

  8. Android之怎样使用ListView列表视图

    ListView 列表视图创建方法: (1)直接使用ListView 组件创建 (2)让Activity继承ListActivity实现 第一种:在XML中直接使用ListView 组件创建 在val ...

  9. c++ 11 thread 初试

    最新的 c++11标准整合进了 线程支持.以下写一个小程序測试一下. 測试代码: #include <iostream> #include <thread> void hell ...

  10. Android之自己定义(上方标题随ViewPager手势慢慢滑动)

    近期非常蛋疼,项目要模仿网易新闻的样式去做.上次把仿网易新闻client的下拉刷新写出来了.这次是ViewPager的滑动,同一时候ViewPager的上面标题下划线尾随者移动.本来通过ViewPag ...