用于ASP.NET Core的Keycloak客户端

mrfwxfqh  于 2023-07-01  发布在  .NET
关注(0)|答案(5)|浏览(181)

是否有任何现有的Keycloak客户端为Asp.net核心?I have found a NuGet package for .net,但它不与核心工作。你有什么想法如何轻松地与这个安全服务器集成(或者使用任何其他替代方案)?

jutyujz0

jutyujz01#

我今天玩了一点这个。最直接的方法就是使用OpenId标准。
在Startup.cs中,我使用了OpenIdConnect身份验证:

public void Configure(...)
    { (...)
         app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme,
            AutomaticAuthenticate = true,
            CookieHttpOnly = true,
            CookieSecure = CookieSecurePolicy.SameAsRequest
        });
        app.UseOpenIdConnectAuthentication(CreateKeycloakOpenIdConnectOptions());`(...)
 }`

OpenIdConnectOptions方法:

private OpenIdConnectOptions CreateKeycloakOpenIdConnectOptions()
    {
        var options = new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme,
            Authority = Configuration["Authentication:KeycloakAuthentication:ServerAddress"]+"/auth/realms/"+ Configuration["Authentication:KeycloakAuthentication:Realm"],
            RequireHttpsMetadata = false, //only in development
            PostLogoutRedirectUri = Configuration["Authentication:KeycloakAuthentication:PostLogoutRedirectUri"],
            ClientId = Configuration["Authentication:KeycloakAuthentication:ClientId"],
            ClientSecret = Configuration["Authentication:KeycloakAuthentication:ClientSecret"],
            ResponseType = OpenIdConnectResponseType.Code,
            GetClaimsFromUserInfoEndpoint = true,
            SaveTokens = true

        };
        options.Scope.Add("openid");
        return options;
    }

在appsettings.json中添加Keycloak的配置:

{
  (...),
  "Authentication": {
    "KeycloakAuthentication": {
      "ServerAddress": "http://localhost:8180",
      "Realm": "demo",
      "PostLogoutRedirectUri": "http://localhost:57630/",
      "ClientId": "KeycloakASPNETCore",
      "ClientSecret": "secret-get-it-in-keycloakConsole-client-credentials"
    }
  }
}

Keycloak客户端配置如下:

如果我想按角色授权用户,我会这样做:
在ConfigureServices方法中添加authorization by claims

public void ConfigureServices(IServiceCollection services)
    {
        (...)

        services.AddAuthorization(options =>
        {
            options.AddPolicy("Accounting", policy =>
            policy.RequireClaim("member_of", "[accounting]")); //this claim value is an array. Any suggestions how to extract just single role? This still works.
        });
    }

我在ValuesController中编辑了get方法(默认Web API模板):

[Authorize(Policy = "Accounting")]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values        
    [HttpGet]
    public Dictionary<string,string> Get()
    {
        var userPrinciple = User as ClaimsPrincipal;
        var claims = new Dictionary<string, string>();

        foreach (var claim in userPrinciple.Claims)
        {
            var key = claim.Type;
            var value = claim.Value;

            claims.Add(key, value);
        }

        return claims;
    }

如果我使用具有会计角色的用户或具有会计角色的组中的用户登录,则应该在地址localhost:57630/API/values上显示我的用户声明。
我希望这对你有用。

编辑:.NET Core 2大家好!我的应用程序的工作方式改变了很多,我还没有完全测试.NET Core 2,但你仍然可以尝试在ConfigureServices中连接到Keycloak:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {

                options.Authority = Configuration["Authentication:KeycloakAuthentication:ServerAddress"] + "/auth/realms/" + Configuration["Authentication:KeycloakAuthentication:Realm"];
                options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidAudiences = new string[] { "curl", "financeApplication", "accountingApplication", "swagger"}
                };
                options.RequireHttpsMetadata = false; //for test only!
                options.SaveToken = true;
                options.Validate();

            });

在Configure中:

app.UseAuthentication();

您可以稍后使用IHttpContextAccessor httpContextAccessor访问令牌,例如:

public KeycloakAuthorizationRequirementHandler(IConfiguration config,
            IHttpContextAccessor httpContextAccessor,
            IMemoryCache memoryCache)
        {
            _config = config;
            _httpContextAccessor = httpContextAccessor;
            _memoryCache = memoryCache;
        }

//获取accessToken

var accessToken = _httpContextAccessor.HttpContext.GetTokenAsync("access_token");

_httpContextAccessor.HttpContext.Items["username"] = username;

告诉我进展如何。

58wvjzkj

58wvjzkj2#

如果你想使用标准的.Net角色Map与Keycloak客户端角色,设置如下:
Startup.cs:

services.AddAuthorization(options =>
    {
        options.AddPolicy("Users", policy =>
        policy.RequireRole("Users"));
    });

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddOpenIdConnect(options =>
    {
        options.Authority = Configuration["Authentication:oidc:Authority"]
        options.ClientId = Configuration["Authentication:oidc:ClientId"];
        options.ClientSecret = Configuration["Authentication:oidc:ClientSecret"];
        options.RequireHttpsMetadata = false;
        options.GetClaimsFromUserInfoEndpoint = true;
        options.SaveTokens = true;
        options.RemoteSignOutPath = "/SignOut";
        options.SignedOutRedirectUri = "Redirect-here";
        options.ResponseType = "code";

    });

appsettings.json:

"Authentication": {
    "oidc": {
      "Authority":"http://your-keycloak-server/auth/realms/your-realm",
      "ClientId":"Your-Client-Name",
      "ClientSecret":"Your-client-secret"
    }
  }

Keycloak客户端设置:

  • 创建新令牌Map器
  • Mapper-Values(输入您自己的客户端名称)

现在,您可以使用标准的authorize role语句将Keycloak客户端角色应用于ASP.NET项目:

[Authorize(Roles = "Users")]
9rbhqvlz

9rbhqvlz3#

对我们有用的是在Startup.cs中设置这些东西(它是基于cookie的身份验证):

public void Configure(...)
{
    (...)
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme,
        AutomaticAuthenticate = true,
        CookieHttpOnly = true,
        CookieSecure = CookieSecurePolicy.SameAsRequest
    });

    app.UseOpenIdConnectAuthentication(CreateOpenIdConnectOptions(_customConfig));
    (...)
}

设置选项:

private OpenIdConnectOptions CreateOpenIdConnectOptions(CustomConfigurationFile configuration)
{
    var options = new OpenIdConnectOptions
    {
        AuthenticationScheme = "oidc",
        SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme,
        Authority = configuration.ServerAddress + "/auth/realms/" + configuration.Realm,
        RequireHttpsMetadata = true,
        PostLogoutRedirectUri = configuration.SystemAddress,
        ClientId = configuration.ClientId,
        ClientSecret = configuration.ClientSecret,
        ResponseType = OpenIdConnectResponseType.Code,
        GetClaimsFromUserInfoEndpoint = true,
        SaveTokens = true
    };
    options.Scope.Clear();
    options.Scope.Add("openid");
    return options;
}
3b6akqbq

3b6akqbq4#

我们能用.net core 5+得到这个问题的最新答案吗?我最近安装了keycloak版本13.0.0,它的工作允许我使用一对夫妇的应用程序单点登录。现在我安装keycloak的真实的原因是为了webapi身份验证。基于上面的答案,我已经安装了Microsoft.AspNetCore.Authentication.OpenIdConnect &一直在努力让它在webapi端和客户端都能工作。

j91ykkif

j91ykkif5#

对于那些为.Net 6后端构建基于KeyCloak的身份验证并寻找基于JWT令牌的解决方案的人来说,这里有一段代码可以添加到Delobytes.AspNetCore.Infrastructure客户端的应用程序的ConfigureServices中:

services.AddKeyCloakAuthentication("SchemeName", true, options =>
    {
        options.Authority = "https://mykeycloakinstallation.com/auth/realms/myrealm"; //"issuer" endpoint
        options.Audience = "account";
        options.OpenIdConfigurationEndpoint = "https://mykeycloakinstallation.com/auth/realms/myrealm/.well-known/openid-configuration";
        options.TokenValidationParameters = new TokenValidationOptions
        {
            RequireExpirationTime = true,
            RequireSignedTokens = true,
            ValidateIssuer = true,
            ValidIssuer = "https://mykeycloakinstallation.com/auth/realms/myrealm",
            ValidateAudience = true,
            ValidAudience = "account",
            ValidateIssuerSigningKey = true,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.FromMinutes(2),
        };
    });

相关问题