使用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调用成功。