欢迎光临散文网 会员登陆 & 注册

9) 接口权限,swagger上锁以及第三方登录

2022-11-10 18:56 作者:紫檀清香  | 我要投稿

打开swagger,任意访问api,可以看到不用任何验证就能访问。对于绝大部系统而言这都是一个致命的问题。接下来我们就配置接口授权验证,先来看一下abp里面授权验证

“授权用于在应用程序中判断是否允许用户执行某些特定的操作.ABP扩展了ASP.NET Core 授权, 将 权限 添加为自动策略并且使授权系统在 应用服务 同样可用.所以ASP.NET Core授权的功能特性和它的文档在基于ABP的应用程序是可用的. ”(https://docs.abp.io/zh-Hans/abp/latest/Authorization)

先来看一实现

授权验证2

可以看到只需要添加[Authorize]就可以完成简单的授权验证,api在没有获得授权的情况下返回了401,需要授权就能正常调用api

  • 接下来配置一下 swagger里面关于 OAuth的功能,方便开发调试。

CmsWebModule里面的ConfigureServices替换AddSwaggerGenAddAbpSwaggerGenWithOAuth,这里需要注意的是授权地址和作用域的值,要在openiddictapplications表中已经存在的数据。

appsettings.json


CmsWebModule.cs

 


  • ConfigureServices里面将上述两个方法使用,这时swagger授权按钮已经出来了(别忘记在控制添加[Authorize])。一起来看看效果

swagger授权按钮已经出来了。一起来看看效果

在弹出授权框时,我这里"client_id:"已经默认填上,是因为配置了默认值(如下)

 


这里有个问题:在swagger里面退出但并没有真正的清除登录信息。发现用户的状态还是登录状态,同时刷新swagger页面时发现授权的状态没有保持。看了几个官方的例子发现他们也是这样使用的,不知道他们的有没有这个问题(https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.HttpApi.Host/Ids2OpenIdHttpApiHostModule.cs) 目前本人还未有更好的解决办法,暂时想到解决的办法有:

  1. 使用中间件拦截swagger页面,在按钮【logout】直接改成 跳转(/account/logout),这样也可以清除登录信息。

  2. 使用自定义的登录页面,就是在进入swagger之前先验证。 这样就必须要使用swagger里面自带的授权弹窗。

swagger里面退出

swagger上锁、授权先到这里,后面找个更好的办法再来解决。目前这样也不影响使用。

接下来进行第三方的授权登录,这里使用github进行身份认证。(多账户的统一登录)

打开GitHub,进入开发者设置界面(https://github.com/settings/developers),新建一个 oAuth App,把用到的几个参数放在appsettings.json中

开发者设置界面


多账户的统一登录(大家可以看一下这位大佬的文章https://juejin.cn/post/6844904053411938311),这里使用的是建立一个第三方用户表(appUserThirdAuth)用于关联已有的用户表(appUser) appUserThirdAuth 表字段如下


大概分析一下,第三方身份认证授权的流程(github为例,可参考官方文档 https://docs.github.com/cn/rest/apps/oauth-applications#check-a-token )

  1. 根据参数生成GitHub重定向的地址,跳转到GitHub登录页进行登录

  2. 登录成功之后会跳转到我们的回调地址,回调地址会携带code参数

  3. 拿到code参数,就可以换取到access_token

  4. 有了access_token,可以调用GitHub获取用户信息的接口

  5. 拿到用户信息后

    随后就可以直接调用登录获取token,完成整个登录流程

    • 如果这个用户已经绑定了授权验证(即在AppUserThirdAuth已经有数据)

    • 如果没用绑定则需要用户进行登录(没有则注册),登录成功时自动绑定当前用户认证的信息

接下来开启代码实站阶段

  • 先把appsettings.json里面的配置统一读取,注入服务中就可以直接使用实体类 在YiAim.Cms.Domain.Shared新建Options文件夹,里面存放配置对应的实体,如:AppOptions,代码太多只展示部分

  


  • 在CmsDomainSharedModule里面读取配置内容

    需要使用时在构造函数里面注入 IOptionsOptions 即可


  • YiAim.Cms.Application.Contracts新建Authorize文件夹,然后新建IAuthorizeService,IOAuthService

  

在 YiAim.Cms.Application 里面写实现请求,直接新建Authorize文件夹,新建StateManager.cs(状态管理器主要用于控制请求限制)、ThirdOAuthServiceBase第三方授权的基础请求服务,后面的第三方授权服务都应继承它,GithubServicegithub授权服务,AuthorizeService暴露的授权服务,具体看代码实现

这里涉及到http请求,在构造函数中依赖注入IHttpClientFactory,在 ConfigureServices里配置 context.Services.AddHttpClient()。使用IHttpClientFactory创建HttpClient StateManager.cs

 


ThirdOAuthServiceBase.cs

AuthorizeService.cs

 


运行项目打开swagger就会看到 多了Authorize

authorize

测试"{type}输入github,因为我们这里支持多平台的授权认证,目前仅实现github

  1. 先调用/oauth/github拿到授权链接

  2. 访问授权链接到github授权服务器拿到code,state参数,就可以进行获取access token.可以看到https://localhost:44377/account/auth?code=71757f3b53404b820602&state=dfaf1ddd4cff400ca0df41c194bc8871 这个地址是没有办法跳转过来的,因为这个地址还不存在,先手动将参数拿到

  3. 将参数放到 /oauth/{type}/token 里进行请求就可以获得token (演示这里没有数据是我接口返回的问题,后面会根据实际场景调整这些接口)

有了第三方的用户信息就可以进行我们的授权认证逻辑处理(见:第三方身份认证授权的流程),到此需要第三方授权认证的关键实现逻辑已经实现的差不多了。 由于篇幅太长,本章就到此结束。下章将继续补充完整第三方授权登录的功能



9) 接口权限,swagger上锁以及第三方登录的评论 (共 条)

分享到微博请遵守国家法律