2017-05-05 60 views
0

是否有可能以某种方式延长IdentityServer4运行自定义验证逻辑?我有要求对一些现有的自定义身份系统验证凭据,并努力找到一个扩展点(他们使用自定义协议)。 所有这些现有的系统都具有客户端知道的API密钥的概念。 IdentityServer作业现在应该是验证此API密钥,并从系统中提取一些现有的声明。 我想象做这样的事情:如何自定义身份验证提供者融入IdentityServer4

POST /connect/token 
    custom_provider_name=my_custom_provider_1& 
    custom_provider_api_key=secret_api_key 

然后我做我的逻辑调用my_custom_provider_1,验证API密钥,获得索赔,并将它们传递回IdentityServer流做休息。

这可能吗?

+0

你不会除非使用标准协议(openid connect,oauth),否则可以使用现有的身份服务器客户端。 – rawel

+0

你最终得到了这个工作吗?如果是这样,请分享您的工作方式。 – stt106

回答

5

我假设你有过客户端的控制,并请求他们做,这样可以使你的身份服务器的相应电话。

可以使用自定义的验证逻辑,毕竟那是ResourceOwnerPassword流是怎么一回事:客户传递信息的连接/令牌端点和你编写代码来决定什么是信息化手段,并决定是否这足以验证该客户端。你一定会被去人迹罕至的地方,做你想做什么,但因为约定说,客户端传递的信息是一个usernamepassword

在你Startup.ConfigureServices,你将需要添加一个IResourceOwnerPasswordValidator的自己的实现,有点像这样:

services.AddTransient<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>(); 

然后在类中,你可以做的ValidateAsync方法的任何逻辑,你想,以决定是否将context.Result设置为成功GrantValidationResult,或者失败。有一件事可以帮助你,那就是ResourceOwnerPasswordValidationContext可以访问原始请求。因此,您添加到原始调用connect/token端点的任何自定义字段都将可供您使用。这是你可以添加自定义字段(提供者名称,API密钥等)的地方。

祝你好运!

编辑:以上可以工作,但真的是滥用标准拨款/流。 OP使用IExtensionGrantValidator接口推出自己的授权类型和认证逻辑的方法更好。例如:

呼叫从客户机到身份服务器:

POST /connect/token 
grant_type=my_crap_grant& 
scope=my_desired_scope& 
rhubarb=true& 
custard=true& 
music=ska 

与DI注册您的扩展补助:

services.AddTransient<IExtensionGrantValidator, MyCrapGrantValidator>(); 

和实现批验证:

public class MyCrapGrantValidator : IExtensionGrantValidator 
{ 
// your custom grant needs a name, used in the Post to /connect/token 
public string GrantType => "my_crap_grant"; 

public async Task ValidateAsync(ExtensionGrantValidationContext context) 
{ 
// Get the values for the data you expect to be used for your custom grant type 
var rhubarb = context.Request.Raw.Get("rhubarb"); 
var custard = context.Request.Raw.Get("custard"); 
var music = context.Request.Raw.Get("music"); 

if (string.IsNullOrWhiteSpace(rhubarb)||string.IsNullOrWhiteSpace(custard)||string.IsNullOrWhiteSpace(music) 
{ 
// this request doesn't have the data we'd expect for our grant type 
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant); 
return Task.FromResult(false); 
} 

// Do your logic to work out, based on the data provided, whether this request is valid or not 
if (bool.Parse(rhubarb) && bool.Parse(custard) && music=="ska") 
{ 
// This grant gives access to any client that simply makes a request with rhubarb and custard both true, and has music equal to ska. You should do better and involve databases and other technical things 
var sub = "ThisIsNotGoodSub"; 
context.Result = new GrantValidationResult(sub,"my_crap_grant"); 
Task.FromResult(0); 
} 

// Otherwise they're unauthorised 
context.Result = new GrantValidationResult(TokenRequestErrors.UnauthorizedClient); 
return Task.FromResult(false); 
} 

}

+2

非常感谢,IResourceOwnerPasswordValidator的工作方式如上所述。不过,我还发现了IExtensionGrantValidator,它也可以正常工作,方法是为每个身份验证提供程序定义一个自定义授予类型,并在调用RequestCustomGrantAsync时将该api键传递给额外的对象。不知怎的,这对我的情况来说感觉更自然,因为我不必滥用用户名/密码字段。这可以吗? – NKnusperer

+1

是的,这看起来像一个更好的方法,而不是滥用'密码'授予类型 – Mashton

+0

@Nnnnnnnnnperer:你可能提供你的解决方案或至少基本步骤?我有类似的情况,我不知道如何使用IExtensionGrantValidator。提前感谢! – user4587483

相关问题