2016-09-22 19 views
1

我正在從ASP.Net Framework轉移到ASP.Net Core。覆蓋ASP.Net Core中的AuthorizeAttribute並響應Json狀態

在ASP.Net應用中使用的Web API 2項目,我可以自定義AuthorizeAttribute這樣的:

public class ApiAuthorizeAttribute : AuthorizationFilterAttribute 
{ 
    #region Methods 

    /// <summary> 
    ///  Override authorization event to do custom authorization. 
    /// </summary> 
    /// <param name="httpActionContext"></param> 
    public override void OnAuthorization(HttpActionContext httpActionContext) 
    { 
     // Retrieve email and password. 
     var accountEmail = 
      httpActionContext.Request.Headers.Where(
        x => 
         !string.IsNullOrEmpty(x.Key) && 
         x.Key.Equals("Email")) 
       .Select(x => x.Value.FirstOrDefault()) 
       .FirstOrDefault(); 

     // Retrieve account password. 
     var accountPassword = 
      httpActionContext.Request.Headers.Where(
        x => 
         !string.IsNullOrEmpty(x.Key) && 
         x.Key.Equals("Password")) 
       .Select(x => x.Value.FirstOrDefault()).FirstOrDefault(); 

     // Account view model construction. 
     var filterAccountViewModel = new FilterAccountViewModel(); 
     filterAccountViewModel.Email = accountEmail; 
     filterAccountViewModel.Password = accountPassword; 
     filterAccountViewModel.EmailComparision = TextComparision.Equal; 
     filterAccountViewModel.PasswordComparision = TextComparision.Equal; 

     // Find the account. 
     var account = RepositoryAccount.FindAccount(filterAccountViewModel); 

     // Account is not found. 
     if (account == null) 
     { 
      // Treat the account as unthorized. 
      httpActionContext.Response = httpActionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); 

      return; 
     } 

     // Role is not defined which means the request is allowed. 
     if (_roles == null) 
      return; 

     // Role is not allowed 
     if (!_roles.Any(x => x == account.Role)) 
     { 
      // Treat the account as unthorized. 
      httpActionContext.Response = httpActionContext.Request.CreateResponse(HttpStatusCode.Forbidden); 

      return; 
     } 

     // Store the requester information in action argument. 
     httpActionContext.ActionArguments["Account"] = account; 
    } 

    #endregion 

    #region Properties 

    /// <summary> 
    ///  Repository which provides function to access account database. 
    /// </summary> 
    public IRepositoryAccount RepositoryAccount { get; set; } 

    /// <summary> 
    ///  Which role can be allowed to access server. 
    /// </summary> 
    private readonly byte[] _roles; 

    #endregion 

    #region Constructor 

    /// <summary> 
    ///  Initialize instance with default settings. 
    /// </summary> 
    public ApiAuthorizeAttribute() 
    { 
    } 

    /// <summary> 
    ///  Initialize instance with allowed role. 
    /// </summary> 
    /// <param name="roles"></param> 
    public ApiAuthorizeAttribute(byte[] roles) 
    { 
     _roles = roles; 
    } 

    #endregion 
} 

在我定製AuthorizeAttribute,我可以檢查賬戶是否有效與否與消息返回HttpStatusCode客戶。

我想在ASP.Net核心做同樣的事情,但沒有OnAuthorization爲我重寫。

我該如何實現ASP.Net Framework中的相同功能?

謝謝,

回答

5

你正在接近這個錯誤。從來沒有真正鼓勵爲此編寫自定義屬性,或者擴展現有屬性。與ASP.NET Core角色仍然是系統的向後兼容性的一部分,但他們現在也不鼓勵。

有一個偉大的2部分系列的一些駕駛體系結構的變化和方式,這是和應該被利用發現here。如果你仍想依靠角色,你可以這樣做,但我會建議使用策略。

連接一個政策執行下列操作:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddAuthorization(options => 
    { 
     options.AddPolicy(nameof(Policy.Account), 
          policy => policy.Requirements.Add(new AccountRequirement())); 
    }); 
} 

我創建了一個Policy枚舉爲了方便。

public enum Policy { Account }; 

裝飾的入口點爲這樣:

[ 
    HttpPost, 
    Authorize(Policy = nameof(Policy.Account)) 
] 
public async Task<IActionResult> PostSomething([FromRoute] blah) 
{ 
} 

AccountRequirement只是一個佔位符,它需要實現IAuthorizationRequirement接口。

public class AccountRequirement: IAuthorizationRequirement { } 

現在我們只需創建一個處理程序並將其連接到DI即可。

public class AccountHandler : AuthorizationHandler<AccountRequirement> 
{ 
    protected override async Task HandleRequirementAsync(
     AuthorizationHandlerContext context, 
     AccountRequirement requirement) 
    { 
     // Your logic here... or anything else you need to do. 
     if (context.User.IsInRole("fooBar")) 
     { 
      context.Succeed(requirement); 
      return; 
     } 
    } 
} 

其他資源

+0

如果我想分析的HttpRequest從報頭獲得的access_token?因爲我想自己實施GitHub OAuth,Google OAuth和Facebook OAuth。第三方庫很難使用。 – Redplane

+0

不是問題,請設置此代碼並檢查「AuthorizationHandlerContext上下文」變量。你會發現它包含帶有標題和路由數據的'HttpRequest'等。 –

+0

其實,我沒有在那裏看到HttpRequest。這裏是我的形象: http://www.mediafire.com/view/c1bv86ktb16qqjj/Screenshot_%2815%29.png – Redplane