使用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();
更多的代码,比如:
- 给IdentityServer project添加登录相关UI,
- 创建MVC client 并添加其对OpenID Connect 协议的支持,
- 将MVC client注册到IdentityServer
参见IdentityServer4 官网: Interactive Applications with ASP.NET Core
参考
- 阮一峰:理解OAuth 2.0
- 理解ASP.NET Core - 基于Cookie的身份认证(Authentication)
- IdentityServer4 官网: Interactive Applications with ASP.NET Core
* 文档声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具