我有使用Web API的ASP.NET MVC 4项目。 在控制器我已经设置了类,要求使用[授权]属性授权。 为了验证我使用ASP.NET成员资格提供,并已我的web.config设置为使用“表单”认证。 这里就是我坚持:
一切是伟大的工作,直到我正在与测试API做了点,我想控制器与[授权]属性固定,所以我可以开始我的成员资格提供测试认证针对用户。 所以,我火了小提琴手和进行相同的调用将授权:与用户名的基本属性:密码从我的成员资格提供像这样:
我得到的回应是401未授权和“验证”我知道在“无WWW验证标题是存在的。” 然后,我意识到API正在寻找一个SHA1编码的关键。 所以,我火了,从搜索的SHA1发电机,并获得自己的用户名散列:密码和更新我的请求头,像这样:
这也不行,我也得到了相同的结果。 此外,我显然需要某种形式的“共享密钥”与服务器使用解码我的用户名/密码。
所以我的问题:
- 如何从服务器获取这个键(或者在这种情况下,IIS虚拟流失VS 2012)。
- 如何使用这个用户名使用名/密码从ASP.NET成员资格提供使在小提琴手验证的调用。
- 我将如何使用这在我的客户端应用程序也作出了同样的调用(C#WPF应用程序)。
- 当与我的HTTP调用SSL相结合这一最佳实践的研究? 如果不是有什么?
提前致谢!
你可以使用基本身份验证与SSL。 在服务器端,我们可以写一个自定义的委托处理程序将通过查询我们注册的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);
}
}
}
}