【问题标题】:WebApi Authentication is not applied to MVCWebApi 身份验证不适用于 MVC
【发布时间】:2015-04-08 19:49:44
【问题描述】:

我有带有自定义身份验证服务器的 ASP.NET MVC 应用程序。当用户想登录时,app弹窗,完成后,token返回,app再通过WebApi登录用户,

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 视图中,它始终为 null,并且这些都不执行

<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>

如何验证用户从 web 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());
        }
    }

【问题讨论】:

  • web api 是否在 mvc 的同一个项目中?
  • 是的,它们在 1 个应用程序中

标签: c# asp.net asp.net-web-api asp.net-mvc-5 asp.net-identity


【解决方案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;
    }
}

【讨论】:

  • 但所有用户数据都存储在声明中,而不是 cookie。所以不能反序列化
  • 您可以将您的索赔数据存储在身份验证 cookie 中。 stackoverflow.com/questions/1149996/…
  • 好的,我明白了。将我所有的声明放在 AuthCookie 中,但 JavaScript 反序列化程序会抛出异常(“无法反序列化声明,循环引用”)
  • 在谷歌上搜索。我相信您一定会在您的上下文中获得循环引用错误的解决方案。
  • 这篇文章可能对你有所帮助。 codeproject.com/Articles/5353/…
猜你喜欢
  • 2016-08-04
  • 2017-03-13
  • 2014-03-20
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-15
  • 2016-10-22
相关资源
最近更新 更多