使用ASP.NET Core与Keycloak实现OpenID Connect认证级别要求

本文详细介绍如何在ASP.NET Core中实现OpenID Connect客户端,并利用Keycloak强制执行认证级别要求。通过acr_values声明配置不同级别的认证方式,包括密码、验证器应用和通行密钥等安全机制。

使用ASP.NET Core OpenID Connect与Keycloak实现认证级别要求

本文探讨了在ASP.NET Core中实现OpenID Connect客户端,并使用Keycloak要求认证级别的过程。应用程序使用Aspire托管。通过acr_values声明在Keycloak中请求认证级别。

代码库:https://github.com/damienbod/IdentityExternalErrorHandling

设置

应用程序使用Aspire实现。ASP.NET Core应用程序使用OpenID Connect客户端对Keycloak服务器进行身份验证。客户端应用程序应要求使用通行密钥进行身份验证。这是通过使用具有LoA3值的acr_values声明强制执行的。LoA3值仅特定于我的实现,可以使用Keycloak服务器上的任何定义来实现。如果使用不同的身份提供商,有些需要预定义的值。如果在Microsoft Entra中实现,可以使用具有持续访问策略的身份验证上下文。

OpenID Connect设置

OpenID Connect客户端使用标准ASP.NET Core接口实现。本演示中客户端不使用OAuth PAR,但如果身份提供商支持,应使用OAuth PAR。使用OAuth PAR时,必须使用PAR事件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.AddOpenIdConnect("keycloak", "keycloak", options =>
{
    options.SignInScheme = IdentityConstants.ExternalScheme;
    options.SignOutScheme = IdentityConstants.ApplicationScheme;
    options.RemoteSignOutPath = new PathString("/signout-callback-oidc-keycloak");
    options.SignedOutCallbackPath = new PathString("/signout-oidc-keycloak");
    options.CallbackPath = new PathString("/signin-oidc-keycloak");
    
    options.Authority = builder.Configuration["AuthConfiguration:IdentityProviderUrl"];
    options.ClientSecret = builder.Configuration["AuthConfiguration:ClientSecret"];
    options.ClientId = builder.Configuration["AuthConfiguration:Audience"];
    options.ResponseType = OpenIdConnectResponseType.Code;
    
    options.Scope.Clear();
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
    options.Scope.Add("offline_access");
    
    options.ClaimActions.Remove("amr");
    options.ClaimActions.MapJsonKey("website", "website");
    
    options.GetClaimsFromUserInfoEndpoint = true;
    options.SaveTokens = true;
    
    options.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Disable;
    
    options.TokenValidationParameters = new TokenValidationParameters
    {
        NameClaimType = "name",
        RoleClaimType = "role",
    };
    
    options.Events = new OpenIdConnectEvents
    {
        // 添加事件处理程序
    };
});

使用acr_values

OnRedirectToIdentityProvider用于设置认证级别要求并将其发送到身份提供商。acr_values声明用于此目的。如果使用OAuth PAR,应使用par事件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
OnRedirectToIdentityProvider = async context =>
{
    // 要求通行密钥
    context.ProtocolMessage.AcrValues = "LoA3";
    
    var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("OnRedirectToIdentityProvider to identity provider. Scheme: {Scheme: }", context.Scheme.Name);
    
    await Task.CompletedTask;
},

Keycloak设置

Keycloak用于实现OpenID Connect服务器并实施认证级别要求。Keycloak为此提供了非常好的文档:

https://www.keycloak.org/docs/latest/server_admin/index.html#features

应用程序要求设置如下:

  • LoA1,级别1,密码
  • LoA2,级别2,验证器应用
  • LoA3,级别3,通行密钥

可以在Realm设置上设置别名:

![Keycloak Realm设置]

客户端浏览器流必须更改以支持LoA流。在流中,根据需要设置级别的值。这是按照Keycloak文档实现的。

![Keycloak客户端浏览器流设置]

注意事项

可以使用Keycloak和acr_values实现和强制执行认证级别。如果使用不同的身份提供商,将需要不同的客户端实现。所有服务器对此的强制执行方式都不同。

验证正确的认证级别是否返回给客户端应用程序非常重要。您还应验证amr声明。

如果此设置不正确,某些身份提供商会返回错误,而某些身份提供商将为此声明返回较弱的值。必须根据所使用的身份提供商实施客户端。

链接

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计