如果你想找出你的客戶,並授權它可以覆蓋的方法ValidateClientAuthentication
。
在Taiseer的例子中,你有聯繫,你會發現一些代碼:
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
context.Validated();
}
和一張紙條,上面說:
當你注意到這個類從 類「OAuthAuthorizationServerProvider」,我們」繼承已經重寫了兩個方法 「ValidateClientAuthentication」和「GrantResourceOwnerCredentials」。 第一種方法負責驗證「客戶端」,在我們的 案例中,我們只有一個客戶端,因此我們將始終返回驗證成功的 。
如果你想驗證客戶端,你必須在其中放置一些邏輯。
通常情況下,您會在您的http請求頭中傳遞clientId
和clientSecret
,以便您可以使用某些數據庫參數驗證客戶端的請求。
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId = string.Empty;
string clientSecret = string.Empty;
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}
if (context.ClientId == null)
{
context.SetError("invalid_client", "Client credentials could not be retrieved through the Authorization header.");
context.Rejected();
return;
}
try
{
// You're going to check the client's credentials on a database.
if (clientId == "MyApp" && clientSecret == "MySecret")
{
context.Validated(clientId);
}
else
{
// Client could not be validated.
context.SetError("invalid_client", "Client credentials are invalid.");
context.Rejected();
}
}
catch (Exception ex)
{
string errorMessage = ex.Message;
context.SetError("server_error");
context.Rejected();
}
return;
}
在樣品上,你會嘗試提取您請求的頭中發送客戶端憑證:
if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
{
context.TryGetFormCredentials(out clientId, out clientSecret);
}
和驗證他們:
// You're going to check the client's credentials on a database.
if (clientId == "MyApp" && clientSecret == "MySecret")
{
context.Validated(clientId);
}
如果客戶端發送錯誤的請求標題您需要拒絕請求:
context.SetError("invalid_client", "Client credentials are invalid.");
context.Rejected();
方法ValidateClientAuthentication
在GrantResourceOwnerCredentials
之前處理。通過這種方式,您可以擴展它並將GrantResourceOwnerCredentials傳遞給您可能需要的額外信息。
在我的應用程序之一,我創建了一個類:
class ApplicationClient
{
public string Id { get; set; }
public string Name { get; set; }
public string ClientSecretHash { get; set; }
public OAuthGrant AllowedGrant { get; set; }
public DateTimeOffset CreatedOn { get; set; }
}
我在ValidateClientAuthentication使用我檢查之後確定clientid和祕密都ok:
if (clientId == "MyApp" && clientSecret == "MySecret")
{
ApplicationClient client = new ApplicationClient();
client.Id = clientId;
client.AllowedGrant = OAuthGrant.ResourceOwner;
client.ClientSecretHash = new PasswordHasher().HashPassword("MySecret");
client.Name = "My App";
client.CreatedOn = DateTimeOffset.UtcNow;
context.OwinContext.Set<ApplicationClient>("oauth:client", client);
context.Validated(clientId);
}
由於你可以看到這裏
context.OwinContext.Set<ApplicationClient>("oauth:client", client);
我正在設置一個Owin變量,我可以在以後閱讀。在現在的GrantResourceOwnerCredentials
可以讀取的情況下,該變量你需要它:
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
ApplicationClient client = context.OwinContext.Get<ApplicationClient>("oauth:client");
...
}
現在,如果你想獲取承載令牌 - 你要使用的所有的安全API調用 - 你需要編碼您clientId
和clientSecret
(BASE64),並通過它在請求頭:
與jQuery Ajax請求會是這個樣子:
var clientId = "MyApp";
var clientSecret = "MySecret";
var authorizationBasic = $.base64.btoa(clientId + ':' + clientSecret);
$.ajax({
type: 'POST',
url: '<your API token validator>',
data: { username: 'John', password: 'Smith', grant_type: 'password' },
dataType: "json",
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
xhrFields: {
withCredentials: true
},
headers: {
'Authorization': 'Basic ' + authorizationBasic
},
beforeSend: function (xhr) {
},
success: function (result) {
var token = result.access_token;
},
error: function (req, status, error) {
alert(error);
}
});
正如你可以看到我還添加了用戶名和密碼 - 與g咆哮型 - 請求中的主體:
data: { username: 'John', password: 'Smith', grant_type: 'password' }
,使得服務器將能夠驗證所述客戶端(+的clientId clientSecret)和用戶(用戶名+密碼)。
如果申請成功,您應該會得到有效的標記:
oAuth.Token = result.access_token;
,你可以在一些地方保存用於下列要求。
現在你可以使用此令牌的所有請求的API:
$.ajax({
type: 'GET',
url: 'myapi/fetchCustomer/001',
data: { },
dataType: "json",
headers: {
'Authorization': 'Bearer ' + oAuth.Token
},
success: function (result) {
// your customer is in the result.
},
error: function (req, status, error) {
alert(error);
}
});
你可能要在啓動過程中添加到您的API的另一件事是SuppressDefaultHostAuthentication
:
config.SuppressDefaultHostAuthentication();
這是HttpConfiguration
的擴展方法。由於您使用的是持票人標記,因此您想要禁止標準的基於cookie的身份驗證機制。
泰賽爾寫了另一系列的articles值得一讀,他解釋了所有這些事情。
我已經創建了github repo,您可以在其中看到它是如何工作的。
Web API是自託管的,並且有兩個客戶端:jQuery和控制檯應用程序。
這是一個完美的,結構良好的答案!我會測試你的解決方案。謝謝。 –
讓我知道它是怎麼回事。我花了一段時間試圖弄清楚所有這些部分如何組合在一起。這並不容易,尤其是因爲網上沒有很多文檔。 – LeftyX
是的,你是對的我花了兩天時間只是爲了瞭解結構,因爲缺乏文檔。我會報告結果:) –