欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

程序员文章站 2022-03-31 11:42:36
上一篇文章中,我们已经完成了服务端数据库的搭建,本篇主要处理多【传统HTTP】【依赖CORE环境】客户端之间协同在线【SSO】以及不需要SSO的场景处理。 目标: 1)实现多类型客户端接入IdentityServer 后文简称【IDSV】 2)实现多客户端分组,使得可以控制分组内客户端进行协同和非协 ......

上一篇文章中,我们已经完成了服务端数据库的搭建,本篇主要处理多【传统HTTP】【依赖CORE环境】客户端之间协同在线【SSO】以及不需要SSO的场景处理。

 

目标:

  1)实现多类型客户端接入IdentityServer 后文简称【IDSV】

  2)实现多客户端分组,使得可以控制分组内客户端进行协同和非协同登录和登出性状表现。

 

 你应该知道的:

  1)关于cookie授权的基本操作,包括但不限于知道一个请求过来之后,客户端验证当前请求不关联用户声明,challenge之后对应是如何发起IDSV认证服务的。

    

IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

 

    上图是Microsoft.AspNetCore.Authorization.AuthorizeAttribute 该特性标签针对Action实现授权控制的全过程,步骤如下       

      1.The request arrives at the server.//请求到达服务器

      2.The authentication middleware calls the default handler's Authenticate method and populates the HttpContext.User object with any available information.//授权中间件调用Authenticate 对应handler并且使用现有信息组装HttpContext.User

      3.The request arrives at the controller action.//请求即将抵达控制器

      4.If the action is not decorated with the [Authorize] attribute, display the page and stop here.//aciton没有Authorize验证要求,那么直接展示当前页面即可

      5.If the action is decorated with [Authorize], the auth filter checks if the user was authenticated.//action有Authorize验证,那么检查下当前user是否已经认证了

      6.If the user was not, the auth filter calls Challenge, redirecting to the appropriate signin authority.//如果这个用户没有认证,那么授权中间件发起问询,直接去找SignIn对应方案

      7.Once the signin authority directs the user back to the app, the auth filter checks if the user is authorized to view the page.//一旦SignIn方案对应服务器授权完毕并返回,这个时候授权中间件检查当前用户是否可以查看当前页面

      8.If the user is authorized, it displays the page, otherwise it calls Forbid, which displays a 'not authorized' page.//如果这个用户允许,那么就展示页面,如果这个用户拒绝了,那么就展示无权限页面。

 

  2)Token是什么?

    token中文翻译为令牌,获取令牌就是为了使客户端能够在令牌标识的范围内进行资源所有者的信息获取,当然获取的来源一般是ProtectApi,本篇暂时不谈。

 

GO:

  1)Core环境下客户端接入

    CORE环境下客户端接入比较简单,只需要知道授权服务器地址,即可完成接入,依赖系统本身的COOKIE组件,我们可以加密轻松实现OIDC流程。

  代码截图如下:

    IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

 其中【1】中代码解释如下:

  DefaultScheme:当前系统验证默认的方案名称

  DefaultSignInScheme:当前系统账户登录时默认的处理方案名称

  DefaultChallengeScheme:当前系统发生问询时,默认的处理方案名称,图示为oidc,该方案为【2】中OpenIdConnnect的对应方案全称

 其中【2】中代码解释如下:

  SignInScheme:远程服务器登录完毕之后,回调客户端登录的处理方案,本文是Cookies对应上方AddCookie(**)的名称。

  RequireHttpsMetadata:是否要求请求必须含HTTPS元数据。

  Authority:授权服务器地址。

  ClientId:当前客户端ID。【该客户端需要在服务端注册,也就是服务端必须得知道这个客户端是谁?】

  ClientSecret:客户端秘钥。【该客户端在服务器上所承认的客户端密码】

  Scope:当前客户端发起问询请求时,所需要请求的资源范围,注意:offline_access决定了授权服务器是否颁发RefreshToken,添加的资源范围必须在服务器针对该客户端配置的允许范围以内,也就是是其子集,当然此处包含对应的Api资源和IdentityResource资源。

  ResponseType:资源服务器回给客户端的类型,图示为Code/IdToken两种回调参数。

  SaveTokens:是否自动保存Token。

  GetClaimsFromUserInfoEndpoint:是否自动根据token请求授权服务器的用户根节点获取用户。

 

完成授权登录之后,可以在cookie中查看到一下cookie资料,该信息也即授权服务器回调SignIn方案所维持登录自动保存的cookie。

IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

别忘了在Configure中注册 app.UseAuthentication();使所有的请求都要验证哦。

做完了以上配置,我们就完成了客户端调用服务器的配置,是不是非常的简单呢~


  2)net framework 4.x环境下接入

    网上找了很多资料,关于IDS4作为服务器,传统HTTP请求接入的资料并不多,这部分只能靠识别GITHUB源码来剖析客户端接入的请求,然后转化成自己的代码,使用HTTP最大的好处就是跨平台和语言,以下内容以C#语言作为示例,别的语言也同理可得。

    

    1.在一个触发登录的唯一入口  发起远程服务器的302请求,代码截图如下:

    IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

    上文中,这部分代码对应的源码如下:

    IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

    Url的组成源码如上,等价于自己拼接URL请求即可,参数部分简单说一下:

      responseMode:这个参数标识了回给客户端的Code/IdToken是通过什么方式

      redirectUri:这个参数也就是服务器所知道的回给客户端的回调地址【在回调中用户自己完成回调参数的使用和处理】

         state/nonce:这两个参数是保证不会有中间人搞事情,state回调的时候检查与发起时是否相同,来判断颁发的这个有没有在中间被人篡改过包。后面那个nonce是一次性的随机码,保证了code只有一次试用机会。

  

   2.回调处理

    不像是core下封装好的组件,回调的部分需要我们自己处理code以及idtoken

    这部分代码截图如下:

    IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

         这部分代码偷懒了,少了很多验证,不过不影响DEMO。

    在完成code获取之后,拿这个code去授权服务器换取真正的token,之后就看怎么玩了,上述代码将id_token  code token以及token对应人存储到cookie中,其实这部分关于cookie的时效,应该做到与返回的TokenResponse的有效时间同步,在当前token失效之后

    发起RefreshToken的接口调用,示意如下:

    IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

    

    以上即完成了netfx客户端接入IDSV服务器,并获取token实际信息的全部过程。

    

 


  3)关于多客户端SSO与非SSO登录的场景处理。

    这部分资料网上也很少,因为IDS4天生的就实现了多客户端协同在线的问题,说到底就是服务端账户在线,新的子客户端连入的时候,直接问询当前账户权限接入是否允许的问题,那么就有场景是需要有些客户端不在输入用户信息,有些必须要强制输入。

    这部分我的逻辑如下:

    1.IDSV实现IAuthorizeInteractionResponseGenerator端口,该端口即是负责客户端同意页面的逻辑,为什么要自定义这个端口呢?因为SSO单点登录的时候,我这边设置了必须要过同意页面,所以在这个逻辑里面处理客户端分组,进而决定是否重新回到登录页面。

    代码如图:

        IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

    以上实现了针对客户端进行分组检查以及强制重登的核心逻辑。
    

    2.与1中同步合作的必须是登录逻辑,核心验证如下:

        IdentityServer4关于多客户端和API的最佳实践【含多类型客户端和API资源,以及客户端分组实践】【中】

      在强制登录的客户端完成登录接口,准备return之前,给当前登录主体,完成新的声明插入。


  

【如果看完之后有所启发,不要吝啬您的点赞哦~】