如何通过OAuth2.0完成Microsoft平台登录验证

参考内容:

OAuth2 in Python | TestDriven.io

代表用户获取访问权限 - Microsoft Graph | Microsoft Learn

OAuth 2.0 Bearer Token Usage

首先需要了解的是,通过Microsoft平台做身份验证,有一些配置时拿到的参数不可或缺(在身份验证的步骤中会用到,不一定是同一个步骤用到),其中包括:

  • client_id:应用程序id

  • client_secret:应用程序密钥

  • authority:

微软提供的authority形如https://login.microsoftonline.com/Enter_the_Tenant_Name_Here,Tenant_Name是租户id,在配置微软账号的时候会给出,是使用者一开始就会已知的参数

  • redirect_uri:身份验证成功后重定向到的指定网址

  • scope:服务端配置的允许客户端访问资源的作用域(类似于能访问到什么样的程度),是OAuth2.0的一种机制

  • state:一串应用提供的随机数,用于方便检测跨站点请求伪造(CSRF)针对客户端的攻击(见微软官方文档说明)

  • code:获取access_token必需的参数,一开始未知,需要服务端返回

访问用户资源的流程如下图所示:

大体上来说包括3步:①获取授权(拿到code) ②通过code拿到access token ③通过access token访问资源。

获取授权(拿到code)

在实践时,通过将client_id,response_type,redirect_uri,scope和state发送给形如authority+/oauth2/v2.0/authorize 的终结点来拿到code。

❀ 需要注意的是,response_type是在这一步必须要携带的参数,且response_type=code,官网还提供了一个参数叫response_mode,但是它不是必需的参数,不加也可以,如果要加,可以把response_mode设置成query或者form_post

拿到access token

会发现通过上一步之后,code会附在redirect_uri的 '?' 之后,形如 redirect_uri?code=xxxx ,所以很容易就能想到通过request.args.get('code')拿到这一串code。

然后我们通过将client_id,client_secret,code,redirect_uri,grant_typeinclude_client_id

发送给形如 authority+/oauth2/v2.0/token 的终结点来拿到access token。

❀ 需要注意的是,在实践中,如果使用了python的oauthlib这个第三方库(一般为了方便还是会使用),在数据中就不需要带有grant_type,因为oauthlib会默认帮你添加(参见web_application.py)

❀ include_client_id的默认值是True,是为了防止发送数据时还未授权(已经授权过其实不需要这个参数,如果为了保险也可以加,没什么影响)

通过access token访问用户资源

通过上一步操作,可以在返回的json格式数据中找到access_token字段,这就是访问用户资源的🔑。(我们离成功已经很接近了!!!!....)

这一步我们只需要把access_token包含在请求标头,向https://graph.microsoft.com/v1.0/me 请求用户资源即可,标头可形如:

header = {

'Authorization': 'Bearer {}'.format(client.token['access_token'])

}

这个意思就是,标头的形式是 Bearer xxxxx(xxxxx是access token)

至于为什么要用Bearer开头,有部分文章说是Authorization头定义的schema,除了Bearer以外还有其他的schema,如果按照官方资料来简单理解,Bearer Token就是一个OAuth2.0访问资源的标准规范,有兴趣可以看这个介绍文档:

RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage (rfc-editor.org)

另外还需要注意的是,这个网关中间的部分确实是/v1.0/,不像其他的终端节点是/v2.0/。

Microsoft Graph是一个可以访问Microsoft云中海量数据的API(稍加尝试,可以发现,如果用的是https://graph.microsoft.com/v1.0/users,会得到所有进行过身份验证的用户的信息....),返回的也是json格式的数据,其中可能包括用户的姓名、邮箱、职业等.....后续可以根据项目和个人需求拿取字段使用。

以上就是根据OAuth2.0在Microsoft平台进行身份验证(单点登录sso)的流程。本文叙述的是通过python来进行的操作,因为python有自带一些第三方库来简化操作,如果使用其他的编程语言,流程也类似,只是可能在向服务端发送凭据时需要特别注意不要漏掉某些字段。

要实现OAuth2.0服务端,需要遵循OAuth2.0协议,实现授权服务器和资源服务器之间的交互。以下是基本的步骤: 1.创建一个ASP.NET Core Web API项目。 2.安装IdentityServer4和Microsoft.AspNetCore.Authentication.JwtBearer NuGet包。 3.在Startup.cs中配置IdentityServer,并添加JwtBearer认证。 4.创建客户端和API资源,并将它们添加到IdentityServer中。 5.实现OAuth2.0授权终结点,例如授权码授权、密码授权、客户端凭证授权等。 6.实现API资源的保护,验证JWT令牌并确保访问令牌有效。 7.测试OAuth2.0授权和保护API资源。 下面是一个简单的示例,演示如何实现OAuth2.0服务端,包括JWT: 1. 在Startup.cs中配置IdentityServer和JwtBearer认证。示例代码如下: ```csharp public void ConfigureServices(IServiceCollection services) { //添加IdentityServer服务 services.AddIdentityServer() .AddInMemoryClients(Config.Clients) .AddInMemoryApiResources(Config.Apis) .AddDeveloperSigningCredential(); //添加JwtBearer认证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = "http://localhost:5000"; //IdentityServer地址 options.RequireHttpsMetadata = false; //HTTPS设置为false,方便测试 options.Audience = "api1"; //API资源名称 }); services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseIdentityServer(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } ``` 2. 创建客户端和API资源。示例代码如下: ```csharp public static class Config { public static IEnumerable<Client> Clients => new List<Client> { new Client { ClientId = "client1", ClientSecrets = { new Secret("secret1".Sha256()) }, AllowedGrantTypes = GrantTypes.ClientCredentials, AllowedScopes = { "api1" } } }; public static IEnumerable<ApiResource> Apis => new List<ApiResource> { new ApiResource("api1", "My API") }; } ``` 3. 实现授权终结点。示例代码如下: ```csharp [HttpPost] [Route("/connect/token")] public async Task<IActionResult> Token([FromBody] TokenRequest request) { if (request.GrantType == "password") { var user = _userService.ValidateCredentials(request.UserName, request.Password); if (user != null) { var accessToken = await _tokenService.CreateAccessTokenAsync(user); return Ok(new { access_token = accessToken, token_type = "Bearer", expires_in = (int)_tokenService.Options.Expiration.TotalSeconds }); } } return BadRequest(new { error = "unsupported_grant_type" }); } ``` 4. 实现API资源的保护。示例代码如下: ```csharp [Authorize] [HttpGet] [Route("test")] public IActionResult Test() { return Ok(new { message = "Hello, World!" }); } ``` 以上是一个基本的OAuth2.0服务端实现,包括JWT。你可以根据自己的需求进行调整和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只野生的桔子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值