web-dev-qa-db-ja.com

ASP.NETCore用のKeycloakクライアント

Asp.net Core用の既存のKeycloakクライアントはありますか? 。net用のNuGetパッケージを見つけました しかし、Coreでは機能しません。このセキュリティサーバーと簡単に統合する方法(または他の代替手段を使用する方法)について何かアイデアはありますか?

6
mikes

今日はこれで少し遊んだ。最も簡単な方法は、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メソッドに クレームによる承認 を追加します。

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(デフォルトのWeb APIテンプレート)でgetメソッドを編集しました:

[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();

            });

そして構成で:

app.UseAuthentication();

後でIHttpContextAccessorhttpContextAccessorを使用してトークンにアクセスできます。次に例を示します。

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;

どうなるか教えてください。

18
frogec

Keycloakクライアントロールで標準の.Netロールマッピングを使用する場合は、次のように設定します。

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クライアント設定:

  • 新しいトークンマッパーを作成する
  • Mapper-Values (独自のクライアント名を入力してください)

これで、標準の承認ロールステートメントを使用して、KeycloakクライアントロールをASP.NETプロジェクトに適用できます。

[Authorize(Roles = "Users")]
4
Imagin8

私たちのために働いたのは、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;
}
1
mikes