2017-05-05 180 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

相關問題