如果您想识别您的客户并对其进行授权,您可以覆盖方法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; }
}
在我检查了 clientId 并且密码正常后,我在 ValidateClientAuthentication 中使用它:
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);
}
});
如您所见,我还在请求正文中添加了用户名和密码 - 以及授权类型:
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 的身份验证机制。
Taiseer 写了另一个系列的articles 值得一读,他解释了所有这些事情。
我创建了一个github repo,您可以在其中查看它的工作原理。
Web API 是自托管的,有两个客户端:jQuery 和控制台应用程序。