2015-02-09 218 views
0

我有自定義身份驗證服務器的ASP.NET MVC應用程序。當用戶試圖登錄時,應用程序的彈出窗口,當他完成後,令牌的回報,然後應用在通過的WebAPI用戶登錄,WebApi身份驗證不適用於MVC

var cl = from d in (this.User.Identity as ClaimsIdentity).Claims 
     select new Claim(d.Type, d.Value); 
var identity = new ClaimsIdentity(cl, "ApplicationCookie"); 
AuthenticationManager.SignIn(identity); 
var name = cl.FirstOrDefault(x => x.Type.ToLower() == "login").Value; 
Thread.CurrentPrincipal = new TaiAuthPrincipal(identity); 
System.Web.Security.FormsAuthentication.SetAuthCookie(name, true); 

,並在每個請求 - 的WebAPI知道誰是用戶,平均User.Identity是定義; 但在MVC的觀點,它總是空,沒有這個執行

<div class="headerPane"> 
    @{ 
     if (User.Identity.IsAuthenticated) 
     { 
      @Html.Partial("HeaderPartialView") 
     } 
     if (HttpContext.Current.User.Identity.IsAuthenticated) 
     { 
      @Html.Partial("HeaderPartialView") 
     } 
     if (System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated) 
     { 
      @Html.Partial("HeaderPartialView") 
     } 
    } 
</div> 

如何驗證來自網頁API用戶MVC? 基於前面的angularjs的應用程序,所以所有授權內容都通過webapi請求在前端完成。所以mvc根本不知道任何事情。

對於豐滿的緣故,這是TaiAuthPrincipal,沒有什麼特別的確實

public class TaiAuthPrincipal : IPrincipal 
    { 
     private IIdentity identity; 
     public IIdentity Identity 
     { 
      get { return identity; } 
     } 

     public bool IsInRole(string role) 
     { 
      var _role = (this.Identity as ClaimsIdentity).Claims.FirstOrDefault(x => x.Type.ToLower().Contains("GroupName".ToLower())); 
      return _role == null ? false : true; 
     } 
     public TaiAuthPrincipal(IIdentity _identity) 
     { 
      this.identity = _identity; 
     } 
     public TaiAuthPrincipal(ClaimsIdentity _identity) 
     { 
      this.identity = _identity as IIdentity; 
     } 
    } 

的Global.asax

void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e) 
     { 
      if (HttpContext.Current.Request.Url.AbsolutePath.StartsWith("/api/")) 
      { 
       System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required); 
      } 
     } 

Startup.cs

public partial class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      app.MapSignalR(); 
      app.UseOAuthBearerAuthentication(new Microsoft.Owin.Security.OAuth.OAuthBearerAuthenticationOptions()); 
     } 
    } 
+0

是網絡API是MVC中的同一個項目? – 2015-02-09 05:56:51

+0

是的,他們在1申請 – 2015-02-09 05:59:23

+0

檢查我的答案 – 2015-02-09 06:05:51

回答

1

如果你是米在同一個MVC應用項目中使用Web Api,那麼你的方式來驗證你的Web請求是完全錯誤的。當你通過調用一個動作來請求你的視圖時,會發生什麼情況,那麼你的mvc項目需要一個已認證的請求,所以你需要做的就是將你的accesstoken保存在客戶端的cookie中,並將其發送到服務器,並用每個請求標識用戶,設置IPrincipal。通過這個答案去它會幫助你

ASP.NET MVC - Set custom IIdentity or IPrincipal

您的代碼看起來像這樣

protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) 
{ 
    HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; 

    if (authCookie != null) 
    { 
     FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); 

     JavaScriptSerializer serializer = new JavaScriptSerializer(); 

     CustomPrincipalSerializeModel serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData); 

     CustomPrincipal newUser = new CustomPrincipal(authTicket.Name); 
     newUser.Id = serializeModel.Id; 
     newUser.FirstName = serializeModel.FirstName; 
     newUser.LastName = serializeModel.LastName; 

     HttpContext.Current.User = newUser; 
    } 
} 
+0

但所有UserData存儲在索賠,而不是餅乾。因此不能反序列化 – 2015-02-09 06:12:22

+1

您可以將您的聲明數據存儲在身份驗證Cookie中。 http://stackoverflow.com/questions/1149996/storing-more-information-using-formsauthentication-setauthcookie – 2015-02-09 06:24:25

+0

好吧,我明白了。將所有聲明放在AuthCookie中,但JavaScript Deserializer會拋出異常(「無法反序列化聲明,循環引用」) – 2015-02-09 08:18:11