ASP.NET MVC3 Custom FormAuthorize

4889 ワード

Webシステムを開発し、ユーザー認証が最も一般的です.最も簡単な方法は、CookieやSessionが存在するかどうかを判断し、ジャンプするかどうかを決定するベースクラスを決定することです.今日はMVCの特性を利用して異なる検証方法を行います.
 
public class CustomAuthorizeAttribute : AuthorizeAttribute  
{  
    protected override bool AuthorizeCore(HttpContextBase httpContext)  
    {  
        UserIdentity user = WebUtility.GetIdentity(httpContext);  
        if (user != null)  
        {  
            httpContext.User = new UserPrincipal(WebUtility.GetIdentity(httpContext));  
        }  
  
        return user != null;  
    }  
  
}  
これはカスタマイズされた検証メカニズムであり、システムが持参した検証コアロジックを書き換え、以下はシステムが持参したロジックである.
protected virtual bool AuthorizeCore(HttpContextBase httpContext)  
{  
    if (httpContext == null)  
    {  
        throw new ArgumentNullException("httpContext");  
    }  
    IPrincipal user = httpContext.User;  
    return user.Identity.IsAuthenticated && (this._usersSplit.Length <= 0 || this._usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) && (this._rolesSplit.Length <= 0 || this._rolesSplit.Any(new Func(user.IsInRole)));  
}  
検証はhttpContextで行われていることがわかる.User属性で判断するので、登録、終了、取得のユーザー情報についてはhttpContext.Userプロパティでいいです.MVCの例からも確かにそうであることがわかります.MVC 3のViewsの_を見てみましょう.LogOnPartial.cshtmlのコード:
@if(Request.IsAuthenticated) {  
    Welcome @User.Identity.Name!  
    [ @Html.ActionLink("Log Off", "LogOff", "Account") ]
  
}  
else {  
    @:[ @Html.ActionLink("Log On", "LogOn", "Account") ]  
}  
では、さっき書き直した検証ロジックを見てみると、大体分かります.まず外部の論理でUserを取得し、Userがログインしていないことを示していない場合は、Userに値を割り当て、ログインをマークします.このUserをどうやって手に入れたか見てみましょう
public static UserIdentity GetIdentity(HttpContextBase context)
{
	var user = GetUser(context);
	return new UserIdentity(user);
}

public static User GetUser(HttpContextBase httpContext)  
{  
    var user = httpContext.Request.Cookies[COOKIE_NAME_KEY];  //       userId
    var info = httpContext.Request.Cookies[COOKIE_INFO_KEY];  //  
    if (user == null || info == null || !info.Value.DESDecrypt(DES_KEY).Contains(user.Value))  //      ,    
    {  
        return null;  
    }  
  
    return new User{UserID = int.parse(user.value)};
}  

これは分かりやすくて、クッキーを通じてユーザーの資料を保存しています.httpContext.UserはIPrincipalタイプなので、UserPrincipalクラスをカスタマイズします.
 
public class UserPrincipal : IPrincipal
{
	public IIdentity Identity { get; private set; }

	public UserPrincipal(IIdentity identity)
	{
		this.Identity = identity;
	}

	public bool IsInRole(string role)
	{
		throw new NotSupportedException();
	}
}

UserPrincipalには何の内容もないようですが、本物のデータはIdentityプロパティに存在するので、UserPrincipalを満たすためにUserIdentityクラスを定義する必要があります.一番上のコードから分かるようにGetIdentity(httpContext)は、UserIdentityインスタンスを返します.
public class UserIdentity : IIdentity  
{  
public UserIdentity//このUserはCookieから復号化されたインスタンス化されたUser である.
    {  
        User = user;  
    }  
  
    public User User { get; private set; }  
  
    public string Name  
    {  
        get { return User == null ? string.Empty : User.UserName; }  
    }  
  
    public string AuthenticationType  
    {  
        get { return "maddemon"; }  
    }  
  
    public bool IsAuthenticated  
    {  
        get { return User != null; }  
    }  
}  
はい、検証コア全体に必要なものは準備ができています.また、最も重要なものは私たちがログインするときにクッキーを書く必要があります.終了するときはクッキーをクリアする必要があります.
public static void SetAuthorizeCookie(HttpContextBase httpContext, User user)  
{  
    httpContext.Response.SetCookie(new HttpCookie(COOKIE_NAME_KEY, user.UserName));  
    httpContext.Response.SetCookie(new HttpCookie(COOKIE_INFO_KEY, (user.UserName + "|" + user.Role).DESEncrypt(DES_KEY)));  
}  
  
public static void RemoveAuthorizeCookie(HttpContextBase httpContext)  
{  
    httpContext.Response.SetCookie(new HttpCookie(COOKIE_NAME_KEY, null) { Expires = DateTime.Now.AddDays(-1) });  
    httpContext.Response.SetCookie(new HttpCookie(COOKIE_INFO_KEY, null) { Expires = DateTime.Now.AddDays(-1) });  
}  
このように、ログインするControllerやActionは、[CustomAuthorize]プロパティを1つ追加するだけで、ログインしていないと自動的にconfigで構成されているログインページにジャンプします.不便ではないでしょうか.よろしいですか.不便ですか.よろしいですか.不便ですか.よろしいですか.不便ですか.はははははは