坚持跨域登录

时间:2014-08-13 18:15:17

标签: c# asp.net-mvc cross-domain

我在Visual Studio中运行一个简单的ASP.NET MVC网站,可以通过多个域在本地访问。

以下是我的问题的复制品:

1)用户使用域1查看网站。 2)用户成功登录。 3)用户使用域2查看站点。 4)站点就像用户从未登录一样。 5)用户使用域1查看站点。 6)该站点现在看到用户再次登录.l

所以基本上用户状态不是跨域保持的。我最初的想法是会话状态不是跨域共享的 - 这是导致这种情况的原因吗?有没有一种简单的方法来解决它?

更新

这是我目前设置身份验证的方式:

[assembly: OwinStartup(typeof(ConfigStartup))]
namespace Yeack
{
    public partial class ConfigStartup
    {
        public void Configuration(IAppBuilder Application)
        {
            public void ConfigureAuthentication(IAppBuilder Application)
            {
                Application.CreatePerOwinContext<RepositoryManager>((x, y) => new RepositoryManager(new SiteDatabase(), x, y));

                Application.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    LoginPath = new PathString("/login"),
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    Provider = new CookieAuthenticationProvider
                    {
                        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<UserManager, User, int>(
                            validateInterval: TimeSpan.FromMinutes(30),
                            regenerateIdentityCallback: (manager, user) => user.GenerateClaimsAsync(manager),
                            getUserIdCallback: (claim) => int.Parse(claim.GetUserId()))
                    }
                });

                Application.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
            }
        }
    }
}

在我的Web.config中,我有以下属性:

<configuration>
    <system.web>
        <customErrors mode="Off" />
    </system.web>
</configuration>

根据这些设置,有没有办法让多域身份验证工作?

1 个答案:

答案 0 :(得分:1)

这是从WebAPI获取令牌授权的方法。

RestUtils.GetTokenData(AppDefaults.UrlAPI, model.User, model.Pass);

此方法持久存在于使用FormsAuthentication

授权model.User的cookie上
Response.SetAuthCookie(model.User, true, model);

的Web.config

<system.web>
    ...
    <!-- Authentication -->
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" slidingExpiration="true" timeout="30" />
    </authentication>
    <sessionState cookieless="UseCookies" mode="InProc" timeout="30" />
</system.web>    

Extension.cs

public static class HttpResponseBaseExtensions
{
    public static int SetAuthCookie<T>(this HttpResponseBase responseBase, string name, bool rememberMe, T userData)
    {
        HttpCookie cookie = FormsAuthentication.GetAuthCookie(name, rememberMe);
        FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
        if (ticket != null)
        {
            FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration,
                ticket.IsPersistent, JsonConvert.SerializeObject(userData), ticket.CookiePath);
            string encTicket = FormsAuthentication.Encrypt(newTicket);
            cookie.Value = encTicket;
            responseBase.Cookies.Add(cookie);
            return encTicket != null ? encTicket.Length : 0;
        }
        return 0;
    }        
}

LoginVM.cs

public class LoginVM
{
    public string User { get; set; }
    public string Pass { get; set; }
}

AccountController.cs

public ActionResult Login(LoginVM model, string returnUrl)
{
    ViewBag.ReturnUrl = returnUrl;
    if (ModelState.IsValid)
    {
        HttpContext.Current.Session["TokenData"] = RestUtils.GetTokenData(AppDefaults.UrlAPI, AppDefaults.ProxyConfig, model.User, model.Pass);
        Response.SetAuthCookie(model.User, true, model);
        return Redirect(returnUrl);
    }
    return View(model);
}

public ActionResult LogOff()
{
    if (HttpContext.Session != null)
    {
        HttpContext.Session.Clear();
        HttpContext.Session.Abandon();
        HttpContext.Session.RemoveAll();
    }

    FormsAuthentication.SignOut();
    return RedirectToAction("Index", "Home");
}