简体   繁体   English

为 OpenIddict MVC Core 2.0 设置自定义范围

[英]Setting up custom scope for OpenIddict MVC Core 2.0

I am fairly new to OpenId and auth in MVC and creating an OpenIddict auth server and client mvc app as shown in the authorization code flow sample.我对 MVC 中的 OpenId 和 auth 还很陌生,并创建了一个 OpenIddict auth 服务器和客户端 mvc 应用程序,如授权代码流示例中所示。 https://github.com/openiddict/openiddict-samples I need to add companyId from my application user to my claims and I'm trying to figure out the steps needed. https://github.com/openiddict/openiddict-samples我需要将我的应用程序用户的companyId添加到我的声明中,我正在尝试找出所需的步骤。

So far I found out the following:到目前为止,我发现了以下内容:

I add the claims and scope to ticket in AuthorizationController.CreateTicketAsync by creating a new ClaimsPrincipal with the new claims added, then adding scope by calling ticket.SetScopes .我将声明和范围添加到AuthorizationController.CreateTicketAsync的票证中,方法是创建一个添加了新声明的新 ClaimsPrincipal,然后通过调用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()));
}

I add the destination to my claims in AuthorizationController.CreateTicketAsync to add it to the IdentityToken.我将目的地添加到 AuthorizationController.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);
}

I add the check for scope and conditionally add claims in UserInfoController我添加了范围检查并有条件地在 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;
}

I add the scope to my options when calling AddOpenIdConnect in my client so it will be added to requests.在我的客户端中调用 AddOpenIdConnect 时,我将范围添加到我的选项中,以便将其添加到请求中。

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

This seems to be working as intended.这似乎按预期工作。

Can someone please comment on these steps or maybe point out a sample that shows this particular kind of implementation?有人可以对这些步骤发表评论,或者指出一个显示这种特殊实现类型的示例吗? (It seems very basic but I have no idea if I have done something really bad in the process). (这看起来很基本,但我不知道我在这个过程中是否做了一些非常糟糕的事情)。

This seems to be working as intended.这似乎按预期工作。

Because that's indeed how you're supposed to implement custom scopes.因为这确实是您应该如何实现自定义范围。

Note that in the most recent OpenIddict versions, you can expose the standard and custom scopes supported by your server in the discovery document (that you can retrieve via http://[host]/.well-known/openid-configuration) so that client applications can easily determine whether a scope is publicly supported or not:请注意,在最新的 OpenIddict 版本中,您可以在发现文档中公开服务器支持的标准和自定义范围(您可以通过 http://[host]/.well-known/openid-configuration 检索),以便客户端应用程序可以轻松确定范围是否受到公开支持:

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

    options.RegisterScopes(
        OpenIdConnectConstants.Scopes.Profile,
        OpenIdConnectConstants.Scopes.Email,
        MyClaimsConstants.Scopes.Company);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM