Использовать внешнюю форму заявки сервера OpenId - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь использовать Keycloak в качестве сервера OpenId для моего основного приложения ASP.Net.

Это почти нормально. Пользователь авторизуется (проходит через атрибут [Authorize]), но его заявки пусты.

Моя конфигурация:

  services.AddAuthentication(options => { options.DefaultScheme = "cookie"; })
    .AddCookie("cookie")
    .AddOpenIdConnect("oidc", options =>
    {
      options.Authority = "http://localhost:8080/auth/realms/master/";
      options.RequireHttpsMetadata = false;
      options.ClientId = "test-client";
      options.ClientSecret = "ee117d6d-25c9-4317-83a0-54c2f252aa89";
      options.GetClaimsFromUserInfoEndpoint = true;
      options.SaveTokens = true;
      options.RemoteSignOutPath = "/SignOut";
      options.SignedOutRedirectUri = "Redirect-here";
      options.ResponseType = "code";
    });

Действие контроллера, которое работает нормально (авторизуется):

[Authorize]
public IActionResult About()
{
  ViewData["Message"] = "Your application description page.";

  return View();
}

Действие контроллера, которое не авторизовано (поскольку для него требуется роль):

[Authorize(Roles = "Administrators")]
public IActionResult About()
{
  ViewData["Message"] = "Your application description page.";

  return View();
}

AccountController.ExternalLoginCallback:

public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
  if (remoteError != null)
  {
    ErrorMessage = $"Error from external provider: {remoteError}";
    return RedirectToAction(nameof(Login));
  }
  var info = await _signInManager.GetExternalLoginInfoAsync(); // it has claims
  if (info == null)
  {
    return RedirectToAction(nameof(Login));
  }

  var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);

  if (result.Succeeded)
  {
    _logger.LogInformation("User logged in with {Name} provider.", info.LoginProvider);
    return RedirectToLocal(returnUrl);
  }
  if (result.IsLockedOut)
  {
    return RedirectToAction(nameof(Lockout));
  }
  else
  {
    ViewData["ReturnUrl"] = returnUrl;
    ViewData["LoginProvider"] = info.LoginProvider;
    var email = info.Principal.FindFirstValue(ClaimTypes.Email);
    return View("ExternalLogin", new ExternalLoginViewModel { Email = email });
  }
}

info объект из приведенного выше фрагмента содержит утверждения, особенно утверждения ролей:

enter image description here

Но когда я вошел в систему и попытался увидеть роли и моллюсков, это emtpy:

var user = await _signInManager.UserManager.GetUserAsync(HttpContext.User); // user is found
var roles = await _signInManager.UserManager.GetRolesAsync(user); // empty
var claims = await _signInManager.UserManager.GetClaimsAsync(user); //empty

Похоже, что Keycloak все делает нормально, но у моего приложения есть проблемы с потреблением утверждений.

Чего мне не хватает?

1 Ответ

0 голосов
/ 02 сентября 2018

Вам необходимо настроить провайдера аутентификации, чтобы он знал, какой тип утверждений использовать для ролей.

Вы можете настроить его следующим образом:

services.AddOpenIdConnect("oidc", options =>
{
    ...

    options.TokenValidationParameters = new TokenValidationParameters
    {
        RoleClaimType = "user_roles"; // or "user_realm_roles"?
    };
});
...