如何在MVC4中包含基本的http身份验证

时间:2013-01-22 19:18:18

标签: c# asp.net-mvc-4

我正在使用MVC4中新的oAuthWebSecurity功能为网站用户进行Facebook身份验证,效果很好。

但是,我想要做的是,仅针对特定控制器,启用基本HTTP身份验证。

我尝试实现自定义操作过滤器(authenticationFilter)来拦截调用并使用自定义代码执行基本身份验证,但代码永远不会遇到AuthorizationFilter的重载。

是否有更简单的方法来实现此功能,而不是创建自定义SimpleMembershipProvider

2 个答案:

答案 0 :(得分:0)

您可以使用[Authorize]过滤器,如下所示。

public class BooksController : ApiController
{
    [Authorize]
    public IEnumerable<Book> Get()
    {
        var result = new List<Book>()
        {
            new Book()
            {
                Author = "John Fowles",
                Title = "The Magus",
                Description = "A major work of mounting tensions " +
                                "in which the human mind is the guinea-pig."
            },
            new Book()
            {
                Author = "Stanislaw Ulam",
                Title = "Adventures of a Mathematician",
                Description = "The autobiography of mathematician Stanislaw Ulam, " +
                                "one of the great scientific minds of the twentieth century."
            }
        };
        return result;
    }
}

有关详细信息,请查看Basic HTTP authentication

我希望这会对你有所帮助。

答案 1 :(得分:0)

您可以使用基本身份验证创建自定义 AuthorizeAttribute 来处理身份验证和授权。此属性用作过滤器,并在请求到达控制器操作或Web API方法之前处理该请求。在重写的 OnAuthorize 方法中,您可以获取标头信息以执行身份验证。

如果您使用ajax向控制器或Web API方法发出请求,请使用基本身份验证来传递凭据以进行授权。这会将凭据放在标头中。要通过使用JQuery ajax 函数的 beforeSend 事件处理程序,可以做到这一点非常简单。使用jquery.base64.js对正在发送的信息进行编码。以下是如何执行此操作的示例。

    getAuthorizationHeader = function (username, password) {
      var authType;
      var up = $.base64.encode(username + ":" + password);
      authType = "Basic " + up;
    };
    return authType;
 };

    $.ajax({
        url: _url,
        data: _data,
        type: _type,
        beforeSend: function (xhr) {
            xhr.setRequestHeader("Authorization", getAuthorizationHeader(username, password));
        },
        success: ajaxSuccessHandler,
        error: ajaxErrHandler
    });

这会对标头中发送的用户名/密码进行编码。请注意,这仅仅依赖于编码是不够安全的,因为它很容易解码。您仍然希望使用HTTPS / SSL来确保通过线路发送的信息是安全的。

在服务器端,您可以创建自定义 AuthorizeAttribute ,从头部获取凭据,对其进行解码,然后执行身份验证/授权过程。请注意,Web API使用的是单独的 AuthorizeAttribute ,而不是控制器。如果您使用的是Web API,请务必在创建自定义 AuthorizeAttribute 时使用 System.Web.Http.AuthorizeAttribute 作为基类。他们有不同的行为。控制器的一个将重定向到登录页面,而Web API的一个返回指示成功或失败的HTTP代码。如果授权无法区分由于授权而导致的失败而非身份验证,我会返回Forbidden的HTTP代码,以便客户端做出相应的反应。

以下是从标头中获取可在自定义 AuthorizeAttribute 中使用的凭据的示例方法。

    private bool GetUserNameAndPassword(HttpActionContext actionContext, out string username, out string password)
    {
        bool gotIt = false;
        username = string.Empty;
        password = string.Empty;
        IEnumerable<string> headerVals;
        if (actionContext.Request.Headers.TryGetValues("Authorization", out headerVals))
        {
            try
            {
                string authHeader = headerVals.FirstOrDefault();
                char[] delims = { ' ' };
                string[] authHeaderTokens = authHeader.Split(new char[] { ' ' });
                if (authHeaderTokens[0].Contains("Basic"))
                {
                    string decodedStr = SecurityHelper.DecodeFrom64(authHeaderTokens[1]);
                    string[] unpw = decodedStr.Split(new char[] { ':' });
                    username = unpw[0];
                    password = unpw[1];
                }
                gotIt = true;
            }
            catch { gotIt = false; }
        }

        return gotIt;
    }

以下是解码此方法中使用的标头数据的代码。

    public static string DecodeFrom64(string encodedData)
    {

        byte[] encodedDataAsBytes

            = System.Convert.FromBase64String(encodedData);

        string returnValue =

           System.Text.Encoding.ASCII.GetString(encodedDataAsBytes);

        return returnValue;

    }

获得用户名和密码后,您可以使用SimpleMembership提供商执行身份验证和授权。