为 OpenIddict MVC Core 2.0 设置自定义范围
Setting up custom scope for OpenIddict MVC Core 2.0
我对 MVC 中的 OpenId 和 auth 以及创建 OpenIddict auth 服务器和客户端 mvc 应用程序相当陌生,如授权代码流示例中所示。 https://github.com/openiddict/openiddict-samples
我需要将我的应用程序用户的 companyId
添加到我的声明中,我正在尝试找出所需的步骤。
到目前为止,我发现了以下内容:
我通过创建一个新的 ClaimsPrincipal 添加了新声明,然后通过调用 ticket.SetScopes
.
添加范围,将声明和范围添加到 AuthorizationController.CreateTicketAsync
中的票证
// 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()));
}
我将目的地添加到我在 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);
}
我添加了范围检查并有条件地在 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);
这似乎按预期工作。
有人可以对这些步骤发表评论,或者指出一个显示这种特定类型实现的示例吗? (这看起来很基础,但我不知道我是否在这个过程中做了一些非常糟糕的事情)。
This seems to be working as intended.
因为这确实是您应该如何实现自定义范围的方式。
请注意,在最新的 OpenIddict 版本中,您可以在发现文档中公开您的服务器支持的标准和自定义范围(您可以通过 http://[host]/.well-known/openid-configuration 检索) ) 以便客户端应用程序可以轻松确定范围是否公开支持:
services.AddOpenIddict(options =>
{
// ...
options.RegisterScopes(
OpenIdConnectConstants.Scopes.Profile,
OpenIdConnectConstants.Scopes.Email,
MyClaimsConstants.Scopes.Company);
});
我对 MVC 中的 OpenId 和 auth 以及创建 OpenIddict auth 服务器和客户端 mvc 应用程序相当陌生,如授权代码流示例中所示。 https://github.com/openiddict/openiddict-samples
我需要将我的应用程序用户的 companyId
添加到我的声明中,我正在尝试找出所需的步骤。
到目前为止,我发现了以下内容:
我通过创建一个新的 ClaimsPrincipal 添加了新声明,然后通过调用 ticket.SetScopes
.
AuthorizationController.CreateTicketAsync
中的票证
// 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()));
}
我将目的地添加到我在 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);
}
我添加了范围检查并有条件地在 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);
这似乎按预期工作。
有人可以对这些步骤发表评论,或者指出一个显示这种特定类型实现的示例吗? (这看起来很基础,但我不知道我是否在这个过程中做了一些非常糟糕的事情)。
This seems to be working as intended.
因为这确实是您应该如何实现自定义范围的方式。
请注意,在最新的 OpenIddict 版本中,您可以在发现文档中公开您的服务器支持的标准和自定义范围(您可以通过 http://[host]/.well-known/openid-configuration 检索) ) 以便客户端应用程序可以轻松确定范围是否公开支持:
services.AddOpenIddict(options =>
{
// ...
options.RegisterScopes(
OpenIdConnectConstants.Scopes.Profile,
OpenIdConnectConstants.Scopes.Email,
MyClaimsConstants.Scopes.Company);
});