如何在MVC4中包含基本的http身份验证
本文关键字:http 身份验证 包含基 MVC4 | 更新日期: 2023-09-27 17:55:06
我正在使用MVC4中的新oAuthWebSecurity功能为该网站的用户进行Facebook身份验证,它工作得很好。
然而,我想做的是只对特定的控制器启用基本的HTTP身份验证。
我已经尝试实现自定义动作过滤器(authenticationFilter)来拦截调用,并使用自定义代码进行基本身份验证,但代码从未达到AuthorizationFilter
的过载。
是否有更简单的方法来实现这个,而不是创建一个自定义的SimpleMembershipProvider
?
您可以使用[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;
}
}
更多信息请查看基本HTTP认证
您可以创建自定义的AuthorizeAttribute来处理使用基本身份验证的身份验证和授权。此属性用作过滤器,并在请求到达控制器操作或Web API方法之前处理请求。在重写的OnAuthorize方法中,您可以获取头信息来执行身份验证。
如果您使用ajax向控制器或Web API方法发出请求,请使用基本身份验证来传递授权凭据。这将凭据放在报头中。通过使用JQuery ajax函数的 beforeend 事件处理程序,可以非常直接地做到这一点。使用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,而不是控制器。一定要使用System.Web.Http。如果使用Web API,在创建自定义AuthorizeAttribute时,将其作为基类。他们有不同的行为。用于控制器的那个将希望重定向到登录页面,而用于Web API的那个将返回指示成功或失败的HTTP代码。如果授权无法区分由于授权而不是身份验证导致的失败,则返回HTTP代码Forbidden,以便客户端可以做出相应的反应。
下面是一个从头中获取凭证的示例方法,可以在自定义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;
}
一旦您有了用户名和密码,您就可以使用simplembership提供程序执行身份验证和授权。