使用cURL通过AzureAd鉴权调用ASP.NET Core Web API
写在前面
为了深刻理解以AzureAD为代表的API鉴权功能,决定使用VisualStudio的WebAPI模板实践一下,最终目标是使用Swagger页面完成鉴权,这部分还在探索中,姑且先将cURL调用的的这部分发布出来。
本篇内容主要参考了微软官方文档,更改了其中一些不符合本地情况的内容。作为个人记录,会改用一些并不标准的表述,敬请见谅。
流程概述
- 将微软账号进行Azure认证;(期间需要进行VISA信用卡信息认证,如果不打算长期使用的话可以直接淘宝买一套信息)
- 在Azure Active Directory(上称AzureAD,下称AAD)分别注册服务端应用(同Web API)和客户端应用,为服务端应用建立作用域(操作名)的公开API,为客户端申请密码并在客户端获取公开API相应的权限;
- 创建VisualStudio(下称VS)的WebAPI模板,用注册好的服务端应用信息配置
appsettings.json,并运行; - 通过终端分别获取授权代码、访问令牌,并用访问令牌调用Web API。
在AAD中,我们所说的在API调用中的服务端和客户端是等价的,对于注册的应用,页面中有一个叫做应用程序(客户端)ID的字段,下面全部使用应用ID代替;
指令/URL中有一些字段需要替换,在此篇内容中均用{}包括,替换时请一并替换掉{}。
详细流程
注册服务端应用
从Azure主页,点击Azure Active Directory图标进入AAD默认目录,左侧栏>管理>应用注册,点击新注册;
使用学校邮箱注册的账号可能存在无权限进入AAD的问题
名称仅作标记,这里取YT-Service,受支持的账户类型和重定向URL保持默认即可,点击注册;
在YT-Service的左侧栏>管理>公开API界面,点击添加范围;
应用程序ID URL保持默认,结构大致为api://{YT-Service_应用ID},点击保存并继续;
作用域名称代表调用API时进行的操作,在VS的WebAPI模板中,这一操作为access_as_user。谁能同意?选择管理员和用户。管理员/用户 同意 显示名称/说明在此实践中不重要,随意填写即可。状态选择已启用。点击添加作用域;
注册客户端应用
返回主页,同样地,点击Azure Active Directory图标进入AAD默认目录,左侧栏>管理>应用注册,点击新注册;
名称这里取YT-Client,受支持的账户类型保持默认即可,重定向URL中,选择平台选择Web,值填入http://localhost,点击注册;
在YT-Client的左侧栏>管理>证书和密码,客户端密码一栏点击新客户端密码,说明和截止期限保持默认即可,点击添加,获得密码的值字段一定妥善保管,再次进入此页面时将无法查看;
在YT-Client的左侧栏>管理>API权限,点击添加权限,选择我的API栏,选择刚才注册的YT-Service,勾选access_as_user,点击添加权限。
至此在AAD上面的操作已经全部完成,观察YT-Service和YT-Client的左侧栏>概述中,目录(租户)ID应该相同,下称此字段为用户ID。
生成并配置VS .NET Core Web APi模板
启动VS,创建新项目,选择ASP .NET Core Web API模板,项目名称仅作标记,这里取TY-API,点击下一步;
框架默认,身份验证类型选择Microsoft标识平台,其余选择默认,点击创建;
有三种方式进行模板配置:
-
登录刚才注册应用的微软账户,选择租户(一般默认),在
拥有的应用程序一栏中选择YT-Service,点击下一步;均默认即可,点击
完成,等待配置结束。 -
在
解决方案资源管理器中Connected Services菜单中,右键点击Microsoft标识平台,选择编辑,其余步骤与方法1相同。 -
在
解决方案资源管理器中进入appsettings.json,更改AzureAd的值:Instance为"https://login.microsoftonline.com/",参考;Domain的值参考在AAD界面鼠标悬停在右上角头像处的提示栏中域字段的值,参考格式为"{xxx}.onmicrosoft.com";TenantId为"{用户ID}";ClientId为"{TY-Service_应用ID}";CallbackPath保持默认为"/signin-oidc";Scopes保持默认为"access_as_user";ClientSecret无需配置,保持默认提示值即可;ClientCertificates无需配置,保持默认空值即可;
在VS的调试菜单选择开始执行(不调试),浏览器会跳转到Swagger界面,记录此页面的{端口号},此时测试API应该会获得401代码,因为我们并没有进行鉴权。
通过终端使用cURL获得鉴权并调用API
此段的{授权代码}和{访问令牌}可能会很长(1300~和1700~)
在浏览器中替换并访问以下网址:
https://login.microsoftonline.com/{用户ID}/oauth2/v2.0/authorize?client_id={TY-Client_应用ID}&response_type=code&redirect_uri=http://localhost&response_mode=query&scope=api://{TY-Service_应用ID}/{作用域名称}
此处作用域名称为access_as_user;
以注册应用的 Azure AD 租户中的用户身份登录。 如有必要,可同意任何访问请求。
浏览器将会重定向到http://localhost/,请观察浏览器的地址栏, URL 格式如下:
http://localhost/?code={授权代码}&session_state={会话状态}
请复制两个参数在接下来的步骤中使用;
在终端中替换并执行以下命令:
curl -X POST https://login.microsoftonline.com/{用户ID}/oauth2/v2.0/token -d "api://{TY-Service_应用ID}/{作用域名称}&client_id={TY-Client_应用ID}&code={授权代码}&session_state={会话状态}&redirect_uri=http://localhost&grant_type=authorization_code&client_secret={TY-Client_应用密码}"
如果输入正确,应会收到类似于以下输出的 JSON 响应:
1 | |
记下{访问令牌},在终端中替换并执行以下命令:
curl -X GET https://localhost:{端口号}/WeatherForecast -ki -H 'Content-Type: application/json' -H "Authorization: Bearer {访问令牌}" -H 'accept: text/plain'
我们得到了如下结果:
1 | |
标志着API调用成功。