2015-02-09 134 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