IdentityServer4 - Authorization Code

本章主要介绍下Authorization Code这种GrantType在IdentityServer中的应用。

在IdentityServer中通过OpenID Connect 协议支持interactive user 认证。

接下来创建MVC application使用IdentityServer做认证。

1、创建MVC Client,通过Nuget下载安装 Microsoft.AspNetCore.Authentication.OpenIdConnect

    1)、在Startup中配置ConfigureServices:

复制代码
public void ConfigureServices(IServiceCollection services)
{
            services.AddControllersWithViews();
            JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

            services.AddAuthentication(options => 
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;//"Cookies";
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;"oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc",options=> 
            {
                options.Authority = "https://localhost:5001";
                options.ClientId = "mvc";
                options.ClientSecret = "secret";
                options.ResponseType = "code";
                options.SaveTokens = true;
            });
}
复制代码

AddAuthentication 添加认证服务依赖注入

设置DefaultScheme = Cookies 作为本地用户的登录,设置DefaultChallengeScheme = oidc,因为需要用户登录使用OpenID Connect协议。

AddCookie 添加处理Cookies处理程序。

AddOpenIdConnect 用作执行OpenID Connect protocol的处理程序。Authority指定了受信任的token service地址(IdentityServer地址),通过ClientIdClientSecret来验证client,SaveTokens用作持续存储从IdentityServer获取到的token,以便后来只需(as they will be needed later)。

    2)、在Startup中配置Configure,确保Authentication Service每次请求都被执行:

复制代码
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
      endpoints.MapDefaultControllerRoute()
               .RequireAuthorization();
});
复制代码

RequireAuthorization 方法禁止匿名访问整个application。

你也可以使用[Authorize]属性,指定Controller或者Action需要authentiation。

   3)、添加Home View显示User Claims 和 Cookies 属性信息、

2、配置IdentityServer

在IdentityServer project中添加支持的OpenID Connect的Scope。

复制代码
public static IEnumerable<IdentityResource> IdentityResources =>
           new List<IdentityResource>
           {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email(),
                new IdentityResources.Phone(),
                new IdentityResources.Address()
           };
复制代码

Startup中配置如下:

var builder = services.AddIdentityServer()
    .AddInMemoryIdentityResources(Config.IdentityResources)
    .AddInMemoryApiScopes(Config.ApiScopes)
    .AddInMemoryClients(Config.Clients)
    .AddTestUsers(TestUsers.Users);

AddInMemoryIdentityResources 将identityResource注册到IdentityServer

AddInMemoryClients 添加mvc Client, mvc client配置如下:

复制代码
new Client
{ 
   ClientId="mvc",
   ClientSecrets={new Secret("secret".Sha256())},
   AllowedGrantTypes={ OidcConstants.GrantTypes.AuthorizationCode },
   //where to redirect to after login
   RedirectUris={ "https://localhost:5002/signin-oidc" },
   //where to redirect to after logout
   PostLogoutRedirectUris ={ "https://localhost:5002/signout-callback-oidc" },

   AllowOfflineAccess = true,
   AlwaysSendClientClaims = true,
   AllowedScopes= new List<string>
   {
      IdentityServerConstants.StandardScopes.OpenId,
      IdentityServerConstants.StandardScopes.Profile,
      IdentityServerConstants.StandardScopes.Address,
      IdentityServerConstants.StandardScopes.Phone,
      IdentityServerConstants.StandardScopes.Email,
      IdentityServerConstants.StandardScopes.OfflineAccess
    }
}
复制代码

3、启动mvc 和 identity server,访问mvc protected controller,将重定向到identity server登录页面;登录之后,将重定向回MVC 客户端,在这里OpenID Connect执行了认证并且user登录在本地设置了cookie。最终MVC呈现页面。

4、添加sign-out

public IActionResult Logout()
{
    //return SignOut("Cookies", "oidc");
return SignOut(CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme); }

这将会清除本地cookie,然后重定向到IdentityServer,IdentityServer将清除cookies并且给user一个链接返回MVC application。

5、获取claims从UserInfo endpoint

 尽管我们在client中配置了scope 可以检索profile 等identity scope,但是identity scope依然不会出现在token里,这时需要在Client设置GetClaimsFromUserInfoEndpoint

复制代码
 .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options=> 
 {
                options.Authority = "https://localhost:5001";
                options.ClientId = "mvc";
                options.ClientSecret = "secret";
                options.ResponseType = "code";
                options.SaveTokens = true;
                options.Scope.Add(OidcConstants.StandardScopes.OpenId);
                options.Scope.Add(OidcConstants.StandardScopes.Address);
                options.Scope.Add(OidcConstants.StandardScopes.Phone);
                options.Scope.Add(OidcConstants.StandardScopes.Email);
                options.Scope.Add(OidcConstants.StandardScopes.Profile);
                options.Scope.Add(OidcConstants.StandardScopes.OfflineAccess);
                options.GetClaimsFromUserInfoEndpoint = true;
});
复制代码

运行结果如下:

 

posted @   云霄宇霁  阅读(181)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示