2016-09-06 113 views
1

所以我有一個調用WebApi方法的MVC應用程序。Web上的基本令牌認證和授權.Api

我的MVC應用程序授權是這樣

public class CustomAuthorizeAttribute : AuthorizeAttribute { 

     private RolesEnum _role; 

     public CustomAuthorizeAttribute() { 
      _role = RolesEnum.User; 
     } 

     public CustomAuthorizeAttribute(RolesEnum role) { 
      _role = role; 
     } 

     protected override bool AuthorizeCore(HttpContextBase httpContext) { 

      User currentUser = (User)httpContext.Session["CurrentUser"]; 

      if (currentUser == null) { 
       return false; 
      } 

      if (currentUser.Role == RolesEnum.User && _role == RolesEnum.Admin) { 
       return false; 
      } 

      return true; 
     } 

該認證是木已成舟調用的WebAPI方法

[HttpPost] 
    public ActionResult Login(string username, string password) 
    { 

     User acc = new User(); 
     acc.Username = username; 
     acc.Password = password; 
     acc = accBL.Login(acc); 

     if (acc != null) { 
      Session.Add("CurrentUser", acc); 
      return RedirectToAction("Index", "Project", null); 
     } else { 
      return View(); 
     } 


    } 

登錄方法看起來像這樣

public User LogIn(User acc) { 
      try { 
       HttpClient client = new HttpClient(); 
       client.BaseAddress = new Uri(BASE_URL); 
       client.DefaultRequestHeaders.Accept.Add(
        new MediaTypeWithQualityHeaderValue("application/json")); 
       HttpResponseMessage response = client.PostAsJsonAsync("api/Account/Login", acc).Result; 

       if (response.IsSuccessStatusCode) { 
        return response.Content.ReadAsAsync<User>().Result; 
       } else { 
        return null; 
       } 

      } catch { 
       return null; 
      } 
     } 

和的WebAPI方法看起來像這樣

[Route("api/Account/Login")] 
     [HttpPost] 
     public IHttpActionResult Login(User userModel) { 
      User user = db.Users.Where(p => p.Username == userModel.Username && p.Password == userModel.Password).FirstOrDefault(); 

      if (user != null) { 
       return Ok(user); 
      } else { 
       throw new HttpResponseException(HttpStatusCode.Unauthorized); 
      } 

     } 

如何在MVC應用程序和WebApi服務之間建立連接。我的授權和認證適用於MVC部分,但我的WebApi服務可以在沒有任何授權/認證的情況下被調用。基於我的例子,我怎樣才能保護我的WebApi?我一直在使用MVC和WebApi工作了大約3周,很多事情我也不太清楚。

我應該只是在公共IHttpActionResult登錄(用戶userModel)中創建一個GUID,並檢查它每次我調用一個方法?我如何將這個GUID傳遞給MVC App,並從MVC傳遞給WebApi?

回答

1

你可以做的是在WebAPI Login()方法中創建某種標記(例如JWT),並返回Ok()響應(對MVC應用程序)。調用API端點的用戶必須將此令牌發回(例如,在自定義「令牌」標頭中)。您可以驗證您在API端點中使用的自定義WebAPI授權屬性中的令牌。

例如。

登錄端點

[Route("api/Account/Login")] 
[HttpPost] 
public object Login(User userModel) { 
    User user = ...; 
    string token = CreateTokenForUser(user); 

    if (user != null) { 
     // return user and token back 
     return new {User = user, Token = token}; 
    } else { 
     throw new HttpResponseException(HttpStatusCode.Unauthorized); 
    } 
} 

自定義驗證過濾器

public class UserAuthAttribute : ActionFilterAttribute, IAuthenticationFilter 
{ 

    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken) 
    { 
     string token = null; 
     IEnumerable<string> tokenHeader; 
     if (context.Request.Headers.TryGetValues("Token", out tokenHeader)) 
      token = tokenHeader.FirstOrDefault(); 

     if (token != null && IsTokenValid(token) 
     { 
      // user has been authenticated i.e. send us a token we sent back earlier 
     } 
     else 
     { 
      // set ErrorResult - this will result in sending a 401 Unauthorized 
      context.ErrorResult = new AuthenticationFailureResult(Invalid token", context.Request); 
     } 
    } 

} 

只有通過驗證的用戶應該被允許訪問其他端點

[Route("api/Values")] 
[HttpGet] 
[UserAuth] 
public object GetValues() { 

    // only requests with a valid token will be able to call this because of the [UserAuth] attribute 
} 
+0

我會在幾個測試!謝謝您的回答! – CiucaS

+0

我已經接受了答案,我拿了一些你發佈的內容並做了一些修改。謝謝! – CiucaS

+0

很高興聽到您找到解決方案!我發佈的想法是從一個已經運作的更大的項目... – ubi