當沒有訪問需要認證(還沒有認證通過)的網站時,瀏覽器自動跳出登入對話框
自定一個 Filter:
public class MyAutheticationAttribute : FilterAttribute, IAuthenticationFilter
{
/* basic 驗證的 http header
* 401 Unauthorizted
* WWW-Authenticate: Basic realm="Secure Area"
* 請求登入
* Authorization: Basic {base64編碼過的登錄信息}
*/
public const string AuthoriztionHeaderName = "Authorization";
public const string WwwAuthenticationHeaderName = "WWW-Authenticate";
public const string BasicAuthenticationScheme = "Basic";
private static Dictionary<string, string> userAccounters;
static MyAutheticationAttribute()
{
// 為了簡單測試起見,將一些帳號密碼存放到一個靜態欄位中
userAccounters = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
userAccounters.Add("Ian", "1234");
userAccounters.Add("Peter", "1111");
userAccounters.Add("Jay", "2222");
}
// 具體的認證實現
public void OnAuthentication(AuthenticationContext filterContext)
{
IPrincipal user;
if (this.IsAuthenticated(filterContext, out user))
{
filterContext.Principal = user;
}
else
{
this.ProcessUnauthenticatedRequest(filterContext);
}
}
//
protected virtual AuthenticationHeaderValue GetAuthenticationHeaderValue(AuthenticationContext filterContext)
{
// Authorization 內容
string rawValue = filterContext.RequestContext.HttpContext.Request.Headers[AuthoriztionHeaderName];
if (string.IsNullOrEmpty(rawValue))
{
return null;
}
string[] split = rawValue.Split(' ');
if (split.Length != 2)
{
return null;
}
return new AuthenticationHeaderValue(split[0], split[1]);
}
// 判斷是否通過驗證
protected virtual bool IsAuthenticated(AuthenticationContext filterContext, out IPrincipal user)
{
user = filterContext.Principal;
if (null != user && user.Identity.IsAuthenticated)
{
return true;
}
AuthenticationHeaderValue token = this.GetAuthenticationHeaderValue(filterContext);
if (null != token && token.Scheme == BasicAuthenticationScheme) // "Basic"
{
string credential = Encoding.Default.GetString(Convert.FromBase64String(token.Parameter));
string[] split = credential.Split(':'); // {UserNamr}:{Password}
if (split.Length == 2)
{
string userName = split[0];
string password;
if (userAccounters.TryGetValue(userName, out password))
{
if (password == split[1])
{
// 認證成功的情況下得到代表請求用戶的 Principal 對象
GenericIdentity identiry = new GenericIdentity(userName);
user = new GenericPrincipal(identiry, new string[0]);
return true;
}
}
}
}
return false;
}
// 沒有通過請求
protected virtual void ProcessUnauthenticatedRequest(AuthenticationContext filterContext)
{
string parameter = string.Format("realm=\"{0}\"", filterContext.RequestContext.HttpContext.Request.Url.DnsSafeHost);
AuthenticationHeaderValue challenge = new AuthenticationHeaderValue(BasicAuthenticationScheme, parameter);
filterContext.HttpContext.Response.Headers[WwwAuthenticationHeaderName] = challenge.ToString();
filterContext.Result = new HttpUnauthorizedResult();
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
// throw new NotImplementedException();
}
}
應用在Controller:
[MyAuthetication]
public class HomeController : Controller
{
public void Index()
{
Response.Write(string.Format("Controller.User: {0}<br/>", this.User.Identity.Name));
Response.Write(string.Format("HttpContext.User: {0}<br/>", this.ControllerContext.HttpContext.User.Identity.Name));
Response.Write(string.Format("Thread.CurrentPrincipal.Identity.Name: {0}<br/>", Thread.CurrentPrincipal.Identity.Name));
}
}