您可以使用帶有SSL的basic authentication。在服務器端,我們可以寫一個自定義的委託處理程序將通過查詢我們註冊的memebership提供商驗證憑據,如果有效,檢索角色和設定現任校長:
public class BasicAuthenticationMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var authHeader = request.Headers.Authorization;
if (authHeader == null)
{
return base.SendAsync(request, cancellationToken);
}
if (authHeader.Scheme != "Basic")
{
return base.SendAsync(request, cancellationToken);
}
var encodedUserPass = authHeader.Parameter.Trim();
var userPass = Encoding.ASCII.GetString(Convert.FromBase64String(encodedUserPass));
var parts = userPass.Split(":".ToCharArray());
var username = parts[0];
var password = parts[1];
if (!Membership.ValidateUser(username, password))
{
return base.SendAsync(request, cancellationToken);
}
var identity = new GenericIdentity(username, "Basic");
string[] roles = Roles.Provider.GetRolesForUser(username);
var principal = new GenericPrincipal(identity, roles);
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
return base.SendAsync(request, cancellationToken);
}
}
我們再註冊此處理在Application_Start
:
GlobalConfiguration.Configuration.MessageHandlers.Add(
new BasicAuthenticationMessageHandler()
);
現在我們可以有一個API控制器將與[授權]裝飾屬性,以確保只有合法的用戶才能訪問它的行動:
[Authorize]
public class ValuesController : ApiController
{
public string Get()
{
return string.Format("Hello {0}", User.Identity.Name);
}
}
好了,現在讓我們來看看一個簡單的客戶端:
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
class Program
{
static void Main()
{
// since for testing purposes I am using IIS Express
// with an invalid SSL certificate I need to desactivate
// the check for this certificate.
ServicePointManager.ServerCertificateValidationCallback +=
(sender, certificate, chain, sslPolicyErrors) => true;
using (var client = new HttpClient())
{
var buffer = Encoding.ASCII.GetBytes("john:secret");
var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(buffer));
client.DefaultRequestHeaders.Authorization = authHeader;
var task = client.GetAsync("https://localhost:44300/api/values");
if (task.Result.StatusCode == HttpStatusCode.Unauthorized)
{
Console.WriteLine("wrong credentials");
}
else
{
task.Result.EnsureSuccessStatusCode();
Console.WriteLine(task.Result.Content.ReadAsAsync<string>().Result);
}
}
}
}
達林感謝,這正是我需要的! – CodeAbundance 2012-07-19 06:14:48
控制器方法中的User.Identity.Name'對我來說是空的,'User.Identity.IsAuthenticated'是'false'。我可以在調試器中看到'Thread.CurrentPrincipal'被設置爲消息處理程序中具有正確用戶名和角色的主體。還有'[授權(角色= ...)]'尊重屬性:如果我使用具有錯誤角色的用戶,則會收到未經授權的響應,並且未達到控制器方法。但是'User.Identity'沒有我在消息處理程序中設置的值。你有什麼想法可能是錯誤的? – Slauma 2012-08-19 14:23:15
@Slauma,我無法重現這一點。也許你可以開始一個新的線程一步一步地解釋如何重現問題(當然從一個空的項目開始)。 – 2012-08-19 14:39:35