2013-10-14 5 views
12

私のアプリケーションでは、必要な情報を提供するまで、権限のあるユーザーにプロファイルページを更新する必要があります。それらがプロファイルを更新する場合、IsProfileCompletedはデータベースで「true」に設定されます。MVCのAuthorizeAttributeをオーバーライドする4

これはコントローラの要求される動作にチェック条件を付けることで可能であることがわかります。 しかし、これはAuthorizeAttributeをカスタマイズすることで行いたいと思います。

私はグーグルで、情報は「StackOverflowed」ですが、混乱しました。私を案内してください。

答えて

33
public class MyAuthorizeAttribute: AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      // The user is not authorized => no need to go any further 
      return false; 
     } 

     // We have an authenticated user, let's get his username 
     string authenticatedUser = httpContext.User.Identity.Name; 

     // and check if he has completed his profile 
     if (!this.IsProfileCompleted(authenticatedUser)) 
     { 
      // we store some key into the current HttpContext so that 
      // the HandleUnauthorizedRequest method would know whether it 
      // should redirect to the Login or CompleteProfile page 
      httpContext.Items["redirectToCompleteProfile"] = true; 
      return false; 
     } 

     return true; 
    } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (filterContext.HttpContext.Items.Contains("redirectToCompleteProfile")) 
     { 
      var routeValues = new RouteValueDictionary(new 
      { 
       controller = "someController", 
       action = "someAction", 
      }); 
      filterContext.Result = new RedirectToRouteResult(routeValues); 
     } 
     else 
     { 
      base.HandleUnauthorizedRequest(filterContext); 
     } 
    } 

    private bool IsProfileCompleted(string user) 
    { 
     // You know what to do here => go hit your database to verify if the 
     // current user has already completed his profile by checking 
     // the corresponding field 
     throw new NotImplementedException(); 
    } 
} 

、その後、あなたはこのカスタム属性を使用して、コントローラのアクションを飾ることができます:

[MyAuthorize] 
public ActionResult FooBar() 
{ 
    ... 
} 
+0

私のmvcアプリケーションでカスタム権限を与えるためにこの例を使用しています。しかし、URLを返すようにリダイレクトしません。私は何かを忘れましたか? – Ranger

+0

もう一度私はここにいる、上の問題は解決されました。私はセッションベースのログインを使用していて、承認後に実行する必要のあるコードを実行することがあります。私はセッションキーの静的プロパティを使用しています。これで私を助けることができますか? 保護オーバーライドブールAuthorizeCore(HttpContextBaseのHttpContext) {IF(string.IsNullOrEmpty(CurrentUser.UserName)|| CurrentUser.UserName == "「)falseを返す 。 がtrueを返します。 } – Ranger

+0

この回答はMVC 5と互換性がありますか、または変更する必要がありますか? – radbyx

0

私はこのコードを取られ、現在ログインしているユーザーかどうかをチェックするために、すなわち、自分自身の変更の一部を追加しましたサーバー上にセッション状態があり、以前と同じくらい高価ではありません。

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authorized = base.AuthorizeCore(httpContext); 
     if (!authorized && !Membership.isAuthenticated()) 
     { 
      // The user is not authorized => no need to go any further 
      return false; 
     } 

     return true; 
    } 
} 
public class Membership 
{ 
    public static SystemUserDTO GetCurrentUser() 
    { 
     // create a system user instance 
     SystemUserDTO user = null; 

     try 
     { 
      user = (SystemUserDTO)HttpContext.Current.Session["CurrentUser"]; 
     } 
     catch (Exception ex) 
     { 
      // stores message into an event log 
      Utilities.Log(ex.Message, System.Diagnostics.EventLogEntryType.Warning); 

     } 
     return user; 
    } 

    public static bool isAuthenticated() 
    { 
     bool loggedIn = HttpContext.Current.User.Identity.IsAuthenticated; 
     bool hasSession = (GetCurrentUser() != null); 
     return (loggedIn && hasSession); 
    } 
} 
関連する問題