当我们在登录一些网站的时候,需要第三方的登录。比如,现在我们要登录简书https://www.jianshu.com/sign_in,我们使用微博登录,点击下方的一个微博的小按钮,就会出现这么一个地址https://api.weibo.com/oauth2/authorize?client_id=1881139527&redirect_uri=http%3a%2f%2fwww.jianshu.com%2fusers%2fauth%2fweibo%2fcallback&response_type=code&state=%257b%257d。乍一看,这是什么玩意啊。我们来分解下:

https://api.weibo.com/oauth2/authorize?
client_id=1881139527&
redirect_uri=http%3a%2f%2fwww.jianshu.com%2fusers%2fauth%2fweibo%2fcallback&
response_type=code&
state=%257b%257d

现在就要引出今天的主角了,oauth2

那什么是oauth2呢?

这是官网

https://open.weibo.com/wiki/授权机制,这是微博的授权机制

,这是阮一峰老师写的一篇对于oauth2的介绍。

oauth2.0是一个委托协议,它可用让那些控制资源的人允许某个应用代表这些人,而不是假冒和模仿这喜人,这个应用从资源的所有者哪里得到授权(authentication)和access token,随后就可以使用这个access token来访问资源。(这里提到的假冒和模仿就是指在客户端复制一份用户名和密码,从而获取响应的权限)。是关于授权(authentication)的,客户端应用可以请求access token,使用tooken就可以访问api资源了。在上述的例子中,是微博给简书授权。

让客户端应用可以代表资源所有者(通常是用户)来访问被保护的资源,如下图:

 

 

 资源所有者(resource owner),他拥有访问api资源的权限,并且他还可以委派权限(delegate)给其他应用来访问api。资源所有者通常是可以使用浏览器的人。

被保护的资源(protected resource)就是资源所有者拥有权限去访问的组件,它可以是很多种形式的,但是webapi的形式还是最常见的。

客户端(client)应用就是代表资源所有者访问被保护资源的一个软件,注意它既不是浏览器,也不是给你钱让你开发软件的人,在oauth2里面,它是指被保护的api资源的消费者。

授权服务器(as)是被受保护的资源所信任的,它可以发行具有特定目的的安全凭据给客户端应用,这个凭据就叫做oauth的access token。

 

 

 授权,如下图

 

 

 授权种类:

  1、authentication code

  2、implicit

  3、resource owner password credentials,直接使用密码凭据(用户名和密码)作为授权来获得access token,只有当资源所有者和客户端之间高度新人的时候并且其它授权方式不可用的时候才可以使用这种授权方式。

  4、client credentials,有时候,资源或者叫资源服务器,并不属于某个最终用户,也就是没有资源所有者对该资源负责,但是客户端应用肯定还是要访问这些资源,这时候就只能使用client credentials这种授权方式了。

其他重要角色和组件:

  1、资源所有者resource owner  

  2、客户端client

  3、被保护资源 protected resource

  4、授权服务器authentication server

  5、access token,它是用来访问被保护资源的凭据,授权服务器只是方形token,被保护资源验证token,客户端队友access token应该是完全健忘的。

  6、scopes,被保护资源那里的一套权限,具有叠加性

  7、refresh token,用来获得access token的凭据,客户端是用refresh token来请求信的access token

通过refresh token来取得新的access token的流程

 

 

 

 

 

 重要端点:

  1、授权端点(authentication endpoint)是用来和资源所有者交互的,资源所有者在这里进行登录(身份认证),然后通过该端点可以对客户端进行授权(authentication grant)。授权服务器首先要验证资源所有者的身份,但是验证的方式并不在oauth2的协议范围内。

  2、token端点(token endpoint),客户端通过向token端点展示它的授权(authorization grant)或refresh token来获取access token。除了implicit之外所有的授权类型都需要使用该端点,因为implicit和access token是直接发行的。

openid connect(oidc)

身份认证和授权。oauth2不是身份认证(authorization)协议,openid connect可以进行身份认证(authorization)。

一个比喻,授权,就好比生牛奶(多用途原料);身份认证,就好比奶茶(一个最终产品),以牛奶为主原料。oauth2,是生牛奶,众多web安全架构的一种多用途的基本成分。oidc,好比奶茶,基于oauth2的身份认证协议,添加了一些组件来提供身份认证的能力。

更高级的协议,扩展并代替了oauth2。openid connect是建立在oauth2协议上的一个简单的身份标识层,所以openid connect兼容oauth2。使用openid connect,客户端应用可以请求identity token,它会和access token一同返回给客户端应用。这个identity token就可以被用来登录客户端应用程序,而客户端应用还可以使用access token来访问api资源。userinfo端点,(oauth2定义了authorization端点和token端点)它允许客户端应用和获取用户的额外信息。定义了不同类型的应用如何从身份识别提供商(idp)安全的获取到这些token。

与oauth 2.0之间的角色映射关系

  1、身份供应商(identity provider,idp)

  2、依赖方(relying party,rp,可以理解wie客户端)

  3、oauth2里面可以分为两部分

    a、资源所有者/客户端应用

    b、授权服务器/被保护资源

  4、身份认证协议里也是两大不分

    a、依赖方

    b、身份提供商

  5、映射oauth2——oidc

   授权服务器/被保护资源——身份提供商进行映射

   资源所有者——–最终用户

   客户端应用—–依赖方(rp)

auth 2.0 与 oidc 角色映射

 

 

 抽象流程:

 

 

 依赖方(rp)发送请求到openid提供商(op,也就是身份提供商)。

openid提供商验证最终用户的身份,并获得了用户委派的授权

openid提供商返回响应,里面呆着id token,也通常带着access token

依赖方现在可以使用access token发送请求到用户信息的端点

用户信息端点返回用户的声明(claims,相当于是用户的信息)。

openid connect身份认证流程

authorization code flow: 

  在authorization code流程里,一个授权码(authorization code)会被返回给客户端,这个授权码可以被直接用来交换id token和access token。该流程也可以在客户端使用授权码兑换access token之前对其身份认证。但是该流程要求客户端的身份认证动作在后台使用client 和secret来获得tokens,这样就不会把tokens暴露给浏览器或者其他访问浏览器的恶意应用了。

  要求客户端应用可以安全的在它和授权服务器之间维护客户端的secret,也就是说只适合这样的客户端应用。它还适合于长时间的访问(通过refresh token)。授权码来自于授权端点,而所有的tokens都来自于token端点。

  authorization code流程的步骤如下:

    客户端准备身份认证请求,请求里包含所需要的参数

    客户端发送请求到授权服务器

    授权服务器对最红用户进行身份认证

    授权服务得最终用户的统一/授权

    授权服务器把最终用户发送回客户端,同时带着授权码

    客户端使用授权码向token端点请求一个响应

    客户端接收到响应,响应的body里面包含在和id token和access token

    客户端验证id token,并获得用户的一些身份信息

implicit flow:

  implicit在请求token的时候不需要明确的客户端身份认证,它使用重定向uri的方式来验证客户端的身份,因为这一点,refresh token也就无法使用了,这同样也不适合于长时间有效的access token。

  所有的tokens都来自于授权端点,而token端点并没有用到。

  该流程主要用于浏览器内的应用,access token和id to恩一同被直接返回给客户端,因为这个原因,这些tokens也会暴露于最终用户和跨域访问该浏览器的其他应用了。它并不适合于长时间的访问。

  implicit流程的步骤如下:

    客户端准备身份认证请求,请求里包含所需要的参数

    客户端发送请求到授权服务器

    授权服务器对最终用户进行身份认证

    授权服务器获得最终用户的同意/授权

    授权服务器把最终用户发送客户端,同事带着id token,如果也请求了access token的话,那么access token也会一同返回。

    客户端验证id token,并获得用户的一些身份信息。

hybrid flow:

  hybrid flow是前两者的混合,在该流程里。有一些tokens和授权码来自于授权重点,而另外一些tokens则来自于token端点。该流程允许客户端立即使用id token,并且只需要一次往返即可获得授权码。这种流程也要求客户端应用可以安全的维护secret,它也适合于长时间的访问。

  hybrid flow的步骤如下:

    客户端准备身份认证请求,请求里包含所需要的参数

    客户端发送请求到授权服务器

    授权服务器对最终用户进行身份认证

    授权服务器获得最终用户的统一/授权

    授权服务器把最终用户发送回客户端,同事带着授权码,根据响应类型的不同,也考嫩恶搞带着一个躲着多个其他的参数

    客户端使用授权码向token端点请求一个响应

    客户端接收到响应,响应的body里面包含着id token和access token

    客户端验证id token,并获得用户的一些身份信息。

三种流程特点的比较

 

 

 返回值类型的比较

 

 

 三种类型,根据response_type的不同,分为:

  response_type=code id_token、response_type=code token、response_type=code id_token token。

  注意:为了表明是openid connect协议的请求,scope参数里必须包含openid。

esponse_type=code id_token

 

 

response_type=code token

 

 

response_type=code id_token token

 

identity server:

建立identity provider项目

dentityserver4.templateshttps://github.com/identityserver/identityserver4.templates

安装工具:

dotnet new -i identityserver4.templates

重置 “dotnet new” 功能列表: dotnet new –debug:reinit

模板:

dotnet new is4empty、 dotnet new is4ui 、dotnet new is4inmem 、dotnet new is4aspid、 dotnet new is4ef 、dotnet new is4admin (收费)

 

使用identity server 建立authorization server: