IdentityServer4 возвращает неизвестные заявки, используя OpenId - PullRequest
0 голосов
/ 09 апреля 2020

Я создал сервер IdentityServer4 из шаблона is4aspid (Basi c IdentityServer, который использует ASP. NET Identity для управления пользователями), он поставляется с 2 примерами пользователей.

После этого Я создал клиент страниц бритвы, следуя инструкциям из IdentityServer4 docs .

Приложение работает, но приложение получает от сервера идентификации неизвестные утверждения, вот они (type=value):

s_hash=tFpbakJatWNQIjaChraJAw
sid=Sj6JGUgztjOIK1Cq8E-HoA
sub=a070c8cc-d962-440c-a796-e0c169e87578
auth_time=1586427090
idp=local
amr=pwd

У меня есть определение клиента сервера в настройках приложения. json как:

{

  "ClientId": "mvc",
  "Enabled": true,
  "ClientName": "Mvc Client",

  "AllowedGrantTypes": [ "client_credentials", "authorization_code" ],
  "RequirePkce": true,
  "ClientSecrets": [ { "Value": "hide_for_privacity" } ],

  "RedirectUris": [ "https://localhost:5001/signin-oidc" ],
  "FrontChannelLogoutUri": "http://localhost:5001/signout-oidc",
  "PostLogoutRedirectUris": [ "http://localhost:5001/signout-callback-oidc" ],

  "AllowOfflineAccess": true,
  "AllowedScopes": [ "openid", "profile", "offline_access", "api1" ]
}

Аутентификация в клиенте настроена следующим образом:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
.AddOpenIdConnect(options =>
{
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.Authority = "http://localhost:5099";
    options.RequireHttpsMetadata = false;
    options.ClientId = "mvc";
    options.ClientSecret = "hide_for_privacity";
    options.ResponseType = "code";
    options.UsePkce = true;
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("offline_access");
    options.SaveTokens = true;
});

Я декодировал возвращенный токен с использованием jwt.io и его полезной нагрузки:

{
  "nbf": 1586427096,
  "exp": 1586427396,
  "iss": "http://localhost:5099",
  "aud": "mvc",
  "nonce": "637220238868623664.MzdjNjI0NmMtNWNhMy00YTg4LWIzYTUtYjcxMTFmMTNlYjhiYWY0ZmM5NTQtNDY1Mi00ZWVhLTlkNjUtY2UzMzIwMjY5NjA4",
  "iat": 1586427096,
  "at_hash": "Z_Cwm-4UzmH8v8PyW2d0Rg",
  "s_hash": "tFpbakJatWNQIjaChraJAw",
  "sid": "Sj6JGUgztjOIK1Cq8E-HoA",
  "sub": "a070c8cc-d962-440c-a796-e0c169e87578",
  "auth_time": 1586427090,
  "idp": "local",
  "amr": ["pwd"]
}

Почему я не получаю имя пользователя и роли, определенные на сервере ??

1 Ответ

1 голос
/ 10 апреля 2020

Прежде всего, нужно подтвердить, что вы добавили роли в базу данных и добавили роли пользователю. В SeedData.cs вы можете заполнить роль следующим образом:

public static void SeedRoles(RoleManager<IdentityRole> roleManager)
{
    if (!roleManager.RoleExistsAsync("NormalUser").Result)
    {
        IdentityRole role = new IdentityRole();
        role.Name = "NormalUser";

        IdentityResult roleResult = roleManager.
        CreateAsync(role).Result;
    }


    if (!roleManager.RoleExistsAsync("Administrator").Result)
    {
        IdentityRole role = new IdentityRole();
        role.Name = "Administrator";

        IdentityResult roleResult = roleManager.
        CreateAsync(role).Result;
    }
}

И добавить роли пользователю в функции EnsureSeedData:

...
SeedRoles(roleMgr);
var alice = userMgr.FindByNameAsync("alice").Result;
if (alice == null)
{
    alice = new ApplicationUser
    {
        UserName = "alice"
    };
    var result = userMgr.CreateAsync(alice, "Pass123$").Result;

    if (!result.Succeeded)
    {
        throw new Exception(result.Errors.First().Description);
    }
    userMgr.AddToRoleAsync(alice,"NormalUser").Wait();
    ...
}

После этого вы можете добавить пользовательские утверждения к токенам:

public class ProfileService : IProfileService
{
    protected readonly UserManager<ApplicationUser> _userManager;


    public ProfileService(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        ApplicationUser user = await _userManager.GetUserAsync(context.Subject);

        IList<string> roles = await _userManager.GetRolesAsync(user);

        IList<Claim> roleClaims = new List<Claim>();
        foreach (string role in roles)
        {
            roleClaims.Add(new Claim(JwtClaimTypes.Role, role));
        }

        //add user claims

        roleClaims.Add(new Claim(JwtClaimTypes.Name, user.UserName));
        context.IssuedClaims.AddRange(roleClaims);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        return Task.CompletedTask;
    }
}

И зарегистрируйтесь в Startup.cs:

var builder = services.AddIdentityServer(options =>
{
    options.Events.RaiseErrorEvents = true;
    options.Events.RaiseInformationEvents = true;
    options.Events.RaiseFailureEvents = true;
    options.Events.RaiseSuccessEvents = true;
})
.AddInMemoryIdentityResources(Config.Ids)
.AddInMemoryApiResources(Config.Apis)
.AddInMemoryClients(Config.Clients)
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<ProfileService>();   <-- add this line

В Config.cs в конфигурации клиента установите для AlwaysIncludeUserClaimsInIdToken значение true, чтобы сделать заявки доступными в ID toke:

AlwaysIncludeUserClaimsInIdToken=true, 

Теперь утверждения находятся внутри идентификатора токена, и вы также можете изменить конфигурацию OID C в клиентском приложении, чтобы задать утверждение роли, используя тип JwtClaimTypes.Role из токена:

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
    ....
    options.TokenValidationParameters.RoleClaimType = "role";

});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...