使用Authorization Code保护Interactive Applications

上一篇介绍了ClientCredentials这一最简单的grant type,通常应用在machine对machine的通信环境有安全保障的场景下。

对于Web Application,SAP以及native/mobile Application等有终端用户参与登录的场景下, 更多使用Authorization Code这一grant type。

在微服务架构下,一个公共的identity server也避免了每个微服务/应用自己重复实现auth功能,保障了登录相关UI的一致用户体验。

  

Authorization code flow (授权码工作流)

ClientCredentials 很容易理解,clientId+ secret相当于用户名密码向IdentityServer换取access token;那么在Authorization Code授权工作流(flow) 中,换取access token发生在哪一步?哪里用到了Authorization code呢?

简单地说,用户认证成功之后,授权服务器不会马上返回AccessToken,而是先返回一个授权码(code),然后浏览器再通过code再去获取Token。

这个code,只能使用一次,而且有时效性,所以是非常安全的。

 

步骤如下: 

(A)用户访问客户端(mvc web application),后者将前者导向认证服务器。

(B)用户在认证服务器上完成认证(输入用户名密码/扫描...,并授权)。

(C)认证成功后,认证服务器将用户导向客户端(mvc)事先指定的"重定向URI"(redirect_uri, well known 'signin-oidc'),同时附上一个授权码(Code)。

(D)客户端(mvc)收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端(mvc)的后台的服务器上完成的,对用户不可见。

(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端(mvc)发送访问令牌(access token)和更新令牌(refresh token)

   (F) 客户端返回cookie给浏览器,后者将token保存在本地cookie中。后续用户再需访问mvc(受保护资源 )时,直接在请求中带上AccessToken即可;

 

重定向到IdentityServer(step A)

可以看到重定向到IdentityServer请求的URL是 authorization_endpoint (https://localhost:5001/connect/authorize)

附带的参数包括:(也就是在mvc config配置的)

  • client_id,
  • redirect_uri(aka callback URL,通常是固定的 https://localhost:5002/signin-oidc)
  • response_type
  • scope

  

 

认证服务器将用户导向客户端事先指定的"重定向URI"(step C)

用户输入用户名密码完成授权后,IdentityServer将用户导向客户端(mvc)事先指定的重定向URI(也即https://localhost:5002/signin-oidc),同时附上一个授权码(Code),

请求方式为Post:

通过payload看到授权码:

 

接下来客户端(mvc)收到授权码后,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端(mvc)的后台的服务器上完成的,对用户不可见。

令牌申请成功后,客户端将其以cookie形式发送给浏览器(response header set-cookie)。

 

 后续用户再需访问mvc(受保护资源 )时,直接在请求中带上AccessToken(cookie)即可:

 

 

客户端(mvc)使用基于cookie的认证方案

将从IdentityServer获取的AccessToken 保存到本地,

options.SaveTokens = true;

 添加 可用于处理Cookies的handler,

.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)

 完整的代码如下:

复制代码
//MVC client Program.cs:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = "oidc";
})
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddOpenIdConnect("oidc", options =>
    {
        options.Authority = "https://localhost:5001";

        options.ClientId = "mvc";
        options.ClientSecret = "secret";
        options.ResponseType = "code";

        //to pull remaining claims from the UserInfo endpoint 
        options.Scope.Add("profile");
        options.GetClaimsFromUserInfoEndpoint = true;

        options.SaveTokens = true;
    });

JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
...

//to ensure the execution of the authentication services on each request
app.UseAuthentication();
app.UseAuthorization();

//navigating to the default controller will trigger authentication handshake
app.MapDefaultControllerRoute().RequireAuthorization();
View Code
复制代码

  

更多的代码,比如: 

  • 给IdentityServer project添加登录相关UI,
  • 创建MVC client 并添加其对OpenID Connect 协议的支持,
  • 将MVC client注册到IdentityServer

参见IdentityServer4 官网: Interactive Applications with ASP.NET Core

 

参考

 

 

文档声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证

posted @   鱼羊雨田  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示