IdentityServer4 IExtensionGrantValidator
IdentityServer4 IExtensionGrantValidator
我有一个基本的 IdentityServer4 令牌服务器,一个 Api,以及一个基于 identityserver4 文档教程使用 client_credentials 的测试客户端应用程序设置。
我们有一个预构建的客户端应用程序,用户可以使用他们现有的凭据登录,该凭据未绑定到 IdentityServer4。客户端应用程序将使用 client_credentials 工作流调用 Api,因为我不想为可能需要访问 Api.
的每个客户端应用程序创建多个用户
将上述设置与 IdentityServer4 结合使用,我可以在 client_Credentials 工作流程中正常工作。我面临的问题是,虽然我不需要个人用户对自己进行身份验证,但我仍然想通过 user_id 知道他们是谁。我可以简单地将 &user_id=9999 添加到令牌请求中,但在发出请求时我找不到从令牌服务器检索此信息的方法。经过一些研究后,我发现了 IExtensionGrantValidator,它允许我添加 cstom 授权类型并拦截请求并进行一些自定义处理。问题是,即使看起来我设置正确,我仍然收到 invalid_grant 错误。
代码如下:
public class CustomGrantValidator : IExtensionGrantValidator
{
public string GrantType => "custom_credentials";
public Task ValidateAsync(ExtensionGrantValidationContext context)
{
return Task.FromResult(context.Result);
}
}
在新的客户端块中:
AllowedGrantTypes =
{
GrantType.ClientCredentials,
"custom_credentials"
},
正在启动
.AddExtensionGrantValidator<CustomGrantValidator>();
我是 IdentityServer4 和 .net Core 的新手,所以我确定我做错了什么或者不理解这里的基本机制。
我发现这个是因为我遇到了同样的错误,但我确信你的验证器是无用的,因为它什么也没做。您需要像这样在上下文中设置结果:
var claims = new List<Claim>();
claims.Add(new Claim("sub", userToken));
claims.Add(new Claim("role", "admin"));
context.Result = new GrantValidationResult(userToken, "delegation", claims: claims);
我见过的每个示例都通过添加此值来设置结果。
为了获得 IExtensionGrantValidator 的成功答案,您必须实现接口 IProfileService。此接口有一个名为 IsActiveAsync 的方法。如果不实现此方法,ValidateAsync 的答案将始终为 false。在这里,我将向您展示一个实现示例:
public class IdentityProfileService : IProfileService
{
//This method comes second
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
//IsActiveAsync turns out to be true
//Here you add the claims that you want in the access token
var claims = new List<Claim>();
claims.Add(new Claim("ThisIsNotAGoodClaim", "MyCrapClaim"));
context.IssuedClaims = claims;
}
//This method comes first
public async Task IsActiveAsync(IsActiveContext context)
{
bool isActive = false;
/*
Implement some code to determine that the user is actually active
and set isActive to true
*/
context.IsActive = isActive;
}
}
然后,您必须在启动页面中添加此实现。
public void ConfigureServices(IServiceCollection services)
{
// Some other code
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddAspNetIdentity<Users>()
.AddInMemoryApiResources(config.GetApiResources())
.AddExtensionGrantValidator<CustomGrantValidator>()
.AddProfileService<IdentityProfileService>();
// More code
}
您的实施可以(而且我认为会)更复杂,但我希望这能为您提供良好的起点。
我有一个基本的 IdentityServer4 令牌服务器,一个 Api,以及一个基于 identityserver4 文档教程使用 client_credentials 的测试客户端应用程序设置。
我们有一个预构建的客户端应用程序,用户可以使用他们现有的凭据登录,该凭据未绑定到 IdentityServer4。客户端应用程序将使用 client_credentials 工作流调用 Api,因为我不想为可能需要访问 Api.
的每个客户端应用程序创建多个用户将上述设置与 IdentityServer4 结合使用,我可以在 client_Credentials 工作流程中正常工作。我面临的问题是,虽然我不需要个人用户对自己进行身份验证,但我仍然想通过 user_id 知道他们是谁。我可以简单地将 &user_id=9999 添加到令牌请求中,但在发出请求时我找不到从令牌服务器检索此信息的方法。经过一些研究后,我发现了 IExtensionGrantValidator,它允许我添加 cstom 授权类型并拦截请求并进行一些自定义处理。问题是,即使看起来我设置正确,我仍然收到 invalid_grant 错误。
代码如下:
public class CustomGrantValidator : IExtensionGrantValidator
{
public string GrantType => "custom_credentials";
public Task ValidateAsync(ExtensionGrantValidationContext context)
{
return Task.FromResult(context.Result);
}
}
在新的客户端块中:
AllowedGrantTypes =
{
GrantType.ClientCredentials,
"custom_credentials"
},
正在启动
.AddExtensionGrantValidator<CustomGrantValidator>();
我是 IdentityServer4 和 .net Core 的新手,所以我确定我做错了什么或者不理解这里的基本机制。
我发现这个是因为我遇到了同样的错误,但我确信你的验证器是无用的,因为它什么也没做。您需要像这样在上下文中设置结果:
var claims = new List<Claim>();
claims.Add(new Claim("sub", userToken));
claims.Add(new Claim("role", "admin"));
context.Result = new GrantValidationResult(userToken, "delegation", claims: claims);
我见过的每个示例都通过添加此值来设置结果。
为了获得 IExtensionGrantValidator 的成功答案,您必须实现接口 IProfileService。此接口有一个名为 IsActiveAsync 的方法。如果不实现此方法,ValidateAsync 的答案将始终为 false。在这里,我将向您展示一个实现示例:
public class IdentityProfileService : IProfileService
{
//This method comes second
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
//IsActiveAsync turns out to be true
//Here you add the claims that you want in the access token
var claims = new List<Claim>();
claims.Add(new Claim("ThisIsNotAGoodClaim", "MyCrapClaim"));
context.IssuedClaims = claims;
}
//This method comes first
public async Task IsActiveAsync(IsActiveContext context)
{
bool isActive = false;
/*
Implement some code to determine that the user is actually active
and set isActive to true
*/
context.IsActive = isActive;
}
}
然后,您必须在启动页面中添加此实现。
public void ConfigureServices(IServiceCollection services)
{
// Some other code
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddAspNetIdentity<Users>()
.AddInMemoryApiResources(config.GetApiResources())
.AddExtensionGrantValidator<CustomGrantValidator>()
.AddProfileService<IdentityProfileService>();
// More code
}
您的实施可以(而且我认为会)更复杂,但我希望这能为您提供良好的起点。