asp.net-mvc-4 – 使用基本HTTP身份验证的MVC4 app WebApi中的SimpleMembership

前端之家收集整理的这篇文章主要介绍了asp.net-mvc-4 – 使用基本HTTP身份验证的MVC4 app WebApi中的SimpleMembership前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试实现具有以下要求的MVC4 Web应用程序:

(a)它仅向经过身份验证的用户提供服务.至于身份验证,我想使用简单的成员身份,因为它是MVC的最新身份验证技术,使我能够定义自己的数据库表,提供开箱即用的OAuth支持,并且可以轻松地与MVC和的WebAPI.

(b)它通过WebApi为移动/ JS客户端公开一些核心功能,这些功能应通过基本HTTP身份验证(SSL)进行身份验证.通常,我会让JS客户端使用对WebApi控制器的jQuery AJAX调用,使用不同用户角色的Authorize属性进行修饰.

(c)理想情况下,在混合环境中我想避免双重身份验证:即,如果用户已通过浏览器进行身份验证,并且正在访问暗示对WebApi控制器操作进行JS调用页面,则(a)机制应该是足够.

因此,虽然(a)由默认的MVC模板覆盖,但(b)需要基本的HTTP身份验证而不需要浏览器的中介.为此,我应该创建一个DelegatingHandler,就像我在这篇文章中找到的那样:http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers.
问题是它的实现需要某种方式从收到的用户名和密码中检索IPrincipal,而WebSecurity类没有为此提供任何方法(登录除外,但我会避免仅为了授权而更改记录的用户),也因为潜在的“混合”环境,如(c)).因此,似乎我唯一的选择是放弃简单的会员资格.有没有人有更好的建议?以下是引用帖子中的相关(略微修改)代码

public interface IPrincipalProvider
{
    IPrincipal GetPrincipal(string username,string password);
}

public sealed class Credentials
{
    public string Username { get; set; }
    public string Password { get; set; }
}

public class BasicAuthMessageHandler : DelegatingHandler
{
    private const string BasicAuthResponseHeader = "WWW-Authenticate";
    private const string BasicAuthResponseHeaderValue = "Basic";

    public IPrincipalProvider PrincipalProvider { get; private set; }

    public BasicAuthMessageHandler(IPrincipalProvider provider)
    {
        if (provider == null) throw new ArgumentNullException("provider");
        PrincipalProvider = provider;
    }

    private static Credentials ParseAuthorizationHeader(string sHeader)
    {
        string[] credentials = Encoding.ASCII.GetString(
            Convert.FromBase64String(sHeader)).Split(new[] { ':' });

        if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) ||
            String.IsNullOrEmpty(credentials[1])) return null;

        return new Credentials
        {
            Username = credentials[0],Password = credentials[1],};
    }

    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,CancellationToken cancellationToken)
    {
        AuthenticationHeaderValue authValue = request.Headers.Authorization;
        if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter))
        {
            Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
            if (parsedCredentials != null)
            {
                Thread.CurrentPrincipal = PrincipalProvider
                    .GetPrincipal(parsedCredentials.Username,parsedCredentials.Password);
            } 
        } 

        return base.SendAsync(request,cancellationToken)
            .ContinueWith(task =>
            {
                var response = task.Result;
                if (response.StatusCode == HttpStatusCode.Unauthorized
                    && !response.Headers.Contains(BasicAuthResponseHeader))
                {
                    response.Headers.Add(BasicAuthResponseHeader,BasicAuthResponseHeaderValue);
                } 
                return response;
            });
    }
}

解决方法

Here is another solution that meets all of your requirements.它使用SimpleMemberhsip,在MVC 4应用程序中混合使用表单身份验证和基本身份验证.它也可以支持授权,但不要将Role属性保留为null.

猜你在找的asp.Net相关文章