9) 接口权限,swagger上锁以及第三方登录
打开swagger,任意访问api,可以看到不用任何验证就能访问。对于绝大部系统而言这都是一个致命的问题。接下来我们就配置接口授权验证,先来看一下abp里面授权验证
“授权用于在应用程序中判断是否允许用户执行某些特定的操作.ABP扩展了ASP.NET Core 授权, 将 权限 添加为自动策略并且使授权系统在 应用服务 同样可用.所以ASP.NET Core授权的功能特性和它的文档在基于ABP的应用程序是可用的. ”(https://docs.abp.io/zh-Hans/abp/latest/Authorization)
先来看一实现


可以看到只需要添加[Authorize]就可以完成简单的授权验证,api在没有获得授权的情况下返回了401,需要授权就能正常调用api
接下来配置一下 swagger里面关于 OAuth的功能,方便开发调试。
CmsWebModule里面的ConfigureServices替换AddSwaggerGen为AddAbpSwaggerGenWithOAuth,这里需要注意的是授权地址和作用域的值,要在openiddictapplications表中已经存在的数据。
appsettings.json
CmsWebModule.cs
在
ConfigureServices里面将上述两个方法使用,这时swagger授权按钮已经出来了(别忘记在控制添加[Authorize])。一起来看看效果

在弹出授权框时,我这里"client_id:"已经默认填上,是因为配置了默认值(如下)
这里有个问题:在swagger里面退出但并没有真正的清除登录信息。发现用户的状态还是登录状态,同时刷新swagger页面时发现授权的状态没有保持。看了几个官方的例子发现他们也是这样使用的,不知道他们的有没有这个问题(https://github.com/abpframework/abp-samples/blob/master/Ids2OpenId/src/Ids2OpenId.HttpApi.Host/Ids2OpenIdHttpApiHostModule.cs) 目前本人还未有更好的解决办法,暂时想到解决的办法有:
使用中间件拦截swagger页面,在按钮【logout】直接改成 跳转(/account/logout),这样也可以清除登录信息。
使用自定义的登录页面,就是在进入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 )
根据参数生成GitHub重定向的地址,跳转到GitHub登录页进行登录
登录成功之后会跳转到我们的回调地址,回调地址会携带code参数
拿到code参数,就可以换取到access_token
有了access_token,可以调用GitHub获取用户信息的接口
拿到用户信息后
随后就可以直接调用登录获取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

测试"{type}输入github,因为我们这里支持多平台的授权认证,目前仅实现github
先调用
/oauth/github拿到授权链接访问授权链接到github授权服务器拿到code,state参数,就可以进行获取access token.可以看到
https://localhost:44377/account/auth?code=71757f3b53404b820602&state=dfaf1ddd4cff400ca0df41c194bc8871这个地址是没有办法跳转过来的,因为这个地址还不存在,先手动将参数拿到将参数放到
/oauth/{type}/token里进行请求就可以获得token (演示这里没有数据是我接口返回的问题,后面会根据实际场景调整这些接口)

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

