Настройка настраиваемой области действия для OpenIddict MVC Core 2.0

Я довольно новичок в OpenId и авторизации в MVC и создаю серверное и клиентское приложение OpenIddict mvc, как показано в примере потока кода авторизации. https://github.com/openiddict/openiddict-samples Мне нужно добавить companyid от пользователя моего приложения к моим претензиям и пытаюсь выяснить необходимые шаги.

До сих пор я узнал следующее:

Я добавляю заявки и область действия к заявке в AuthorizationController.CreateTicketAsync, создавая новую заявку spricipal с добавленными новыми заявками и добавив scop для вызова ticket.SetScopes.

        // Add my specific claims: CompanyId and CompanyName
        var claims = new List<Claim>();
        claims.Add(new Claim(MyClaimsConstants.Claims.CompanyId, user.SelectedCompanyId.ToString()));
        T_Company company = await _companyRepo.GetCompany(user.SelectedCompanyId);
        claims.Add(new Claim(MyClaimsConstants.Claims.CompanyName, company.CompanyName));
        // Create the new identity with the added claims
        var newIdentity = new ClaimsIdentity(principal.Identity, claims);

        principal = new ClaimsPrincipal(newIdentity);

        ....

        if (!request.IsAuthorizationCodeGrantType())
        {
            // Set the list of scopes granted to the client application.
            // Note: the offline_access scope must be granted
            // to allow OpenIddict to return a refresh token.
            ticket.SetScopes(new[]
            {
                OpenIdConnectConstants.Scopes.OpenId,
                OpenIdConnectConstants.Scopes.Email,
                OpenIdConnectConstants.Scopes.Profile,
                OpenIdConnectConstants.Scopes.OfflineAccess,
                OpenIddictConstants.Scopes.Roles,
                MyClaimsConstants.Scopes.Company // <-
            }.Intersect(request.GetScopes()));
        }

Я добавляю пункт назначения к своим утверждениям в AuthrizationController.CreateTicketAsync, чтобы добавить его в IdentityToken.

        foreach (var claim in ticket.Principal.Claims)
        {
            // Never include the security stamp in the access and identity tokens, as it's a secret value.
            if (claim.Type == _identityOptions.Value.ClaimsIdentity.SecurityStampClaimType)
            {
                continue;
            }

            var destinations = new List<string>
            {
                OpenIdConnectConstants.Destinations.AccessToken
            };

            // Only add the iterated claim to the id_token if the corresponding scope was granted to the client application.
            // The other claims will only be added to the access_token, which is encrypted when using the default format.
            if (((claim.Type == OpenIdConnectConstants.Claims.Name || claim.Type == OpenIdConnectConstants.Claims.Nickname) && ticket.HasScope(OpenIdConnectConstants.Scopes.Profile)) ||
                (claim.Type == OpenIdConnectConstants.Claims.Email && ticket.HasScope(OpenIdConnectConstants.Scopes.Email)) ||
                (claim.Type == OpenIdConnectConstants.Claims.Role && ticket.HasScope(OpenIddictConstants.Claims.Roles)) ||
                ((claim.Type == MyClaimsConstants.Claims.CompanyId || claim.Type == MyClaimsConstants.Claims.CompanyName) && ticket.HasScope(MyClaimsConstants.Scopes.Company))) // <-
            {
                destinations.Add(OpenIdConnectConstants.Destinations.IdentityToken);
            }

            claim.SetDestinations(destinations);
        }

Я добавляю проверку объема и условно добавляю претензии в UserInfoController

        if (User.HasClaim(OpenIdConnectConstants.Claims.Scope, MyClaimsConstants.Scopes.Company))
        {
            claims[MyClaimsConstants.Claims.CompanyId] = user.SelectedCompanyId;
            claims[MyClaimsConstants.Claims.CompanyName] = (await _companyRepo.GetCompany(user.SelectedCompanyId))?.CompanyName;
        }

Я добавляю область в мои параметры при вызове AddOpenIdConnect в моем клиенте, чтобы он был добавлен в запросы.

            options.Scope.Add(MyClaimsConstants.Scopes.Company);

Кажется, это работает как задумано.

Может кто-нибудь, пожалуйста. прокомментируйте эти шаги или, может быть, укажите пример, который показывает этот конкретный вид реализации? (Это кажется очень простым, но я понятия не имею, сделал ли я что-то действительно плохое в этом процессе).

/Спасибо

1 ответ

Решение

Кажется, это работает как задумано.

Потому что именно так вы должны реализовывать пользовательские области.

Обратите внимание, что в самых последних версиях OpenIddict вы можете выставлять стандартные и настраиваемые области, поддерживаемые вашим сервером, в документе обнаружения (который можно получить через http://%5Bhost%5D/.well-known/openid-configuration), чтобы клиентские приложения могут легко определить, поддерживается ли область публично или нет:

services.AddOpenIddict(options =>
{
    // ...

    options.RegisterScopes(
        OpenIdConnectConstants.Scopes.Profile,
        OpenIdConnectConstants.Scopes.Email,
        MyClaimsConstants.Scopes.Company);
});
Другие вопросы по тегам