2009-09-17 77 views
12

我正在使用ActionFilterAttribute來執行自定義身份驗證邏輯。該屬性將僅用於包含我的驗證邏輯的派生控制器類。ActionFilterAttribute - 適用於特定控制器類型的操作

這裏是我的控制器,從我的定製控制器類派生和樣本屬性:

public class MyController : CustomControllerBase 
{ 

    [CustomAuthorize(UserType = UserTypes.Admin)] 
    public ActionResult DoSomethingSecure() 
    { 
     return View(); 
    } 

} 

這裏是我的ActionFilterAttribute的例子:

public class CustomAuthorizeAttribute : ActionFilterAttribute 
{ 
    public MyUserTypes UserType { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     myUser user = ((CustomControllerBase)filterContext.Controller).User; 

     if(!user.isAuthenticated) 
     { 
     filterContext.RequestContext.HttpContext.Response.StatusCode = 401; 
     } 
    } 
} 

的偉大工程。

下面是問題:我可以要求僅在我的自定義控制器類型的Actions上使用此屬性嗎?

+1

您的屬性因爲不從AuthroizeAttribute繼承而被破壞,因此無法保證在操作緩存時運行。有關使用緩存的解決方案,請參閱http://blogs.teamb.com/craigstuntz/2009/09/09/38390/。 – 2009-09-17 17:20:48

+0

爲什麼要將操作結果緩存? – 2009-09-17 17:24:12

+0

它會被緩存,因爲有人告訴它被緩存。想象一下,有人將Cache屬性放在父類上,而不會注意到子類型上的損壞屬性。使用與ASP.NET/MVC緩存不兼容的屬性是一個更好的主意。有關選項,請參閱上面的鏈接。 – 2009-09-17 17:29:51

回答

14

你可以把ActionFilter放在類本身上。該課程中的所有動作都將實現ActionFilter。

[CustomAuthorize] 
public class AuthorizedControllerBase : CustomControllerBase 
{ 
} 

public class OpenAccessControllerBase : CustomControllerBase 
{ 
} 

public class MyRealController : AuthorizedControllerBase 
{ 
    // GET: /myrealcontroller/index 
    public ActionResult Index() 
    { 
     return View(); 
    } 
} 
+0

我只是在類中定義ActionFilter的路線(所以它在其他類中不可用)。很高興知道屬性可以在控制器中的所有ActionResults中定義。 – 2009-09-17 17:22:31

7

基於我的系統的評論和約束,我採取了混合方法。基本上,如果請求通過緩存路由來傳遞,或者「用戶」由於任何原因而未設置,那麼認證以正確的方式失敗。

public class CustomAuthorizeAttribute : AuthorizeAttribute 
{ 
    private MyUser User { get; set; } 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
    //Lazy loads the user in the controller. 
    User = ((MyControllerBase)filterContext.Controller).User; 

    base.OnAuthorization(filterContext); 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
    bool isAuthorized = false; 
    string retLink = httpContext.Request.Url.AbsolutePath; 

    if(User != null) 
    { 
     isAuthorized = User.IsValidated; 
    } 

    if (!isAuthorized) 
    { 
     //If the current request is coming in via an AJAX call, 
     //simply return a basic 401 status code, otherwise, 
     //redirect to the login page. 
     if (httpContext.Request.IsAjaxRequest()) 
     { 
     httpContext.Response.StatusCode = 401; 
     } 
     else 
     { 
     httpContext.Response.Redirect("/login?retlink=" + retLink); 
     } 
    } 

    return isAuthorized; 
    } 
} 
+0

如果您在任何「isAuthorized = false」情況下重定向,那麼爲什麼不在最後返回true? – Alex 2009-09-17 22:22:24

+0

在IsAjaxRequest流的情況下,用戶沒有被重定向,所以該方法仍然需要返回。 – 2009-09-18 13:56:13

+0

用於使用AuthorizeAttribute而不是ActionFilterAttribute。解決即使我們沒有登錄也會導致其他問題的問題,即執行具有CustomAuthotize屬性的控制器操作。 – 2012-04-02 14:18:17

相關問題