您的位置 首页 asp.Net

asp.net-mvc – ASP.net身份在删除外部帐户后停止分发外部Cookie

我有一个站点设置,有四个第三方登录服务,Microsoft,VS,Github和Linkedin.一切似乎都很好,我可以登录/退出,添加/删除外部帐户没有问题.

然而,它随机似乎停止了工作.当我尝试使用任何第三方服务登录时,它只会让我回到登录页面.

查看ExternalLoginCallback,看来AuthenticateResult.Identity为null,无法获取外部登录信息.在客户端看它,看起来他们从来没有得到外部登录cookie.

我仍然无法一致地重现这个错误,因此很难确定可能发生的事情.任何帮助都会很棒.

更新1:我能够确定重现的步骤:

>登录具有多个关联登录的帐户
>删除其中一个登录
>在新的浏览器或私人会话中,尝试使用任何第三方帐户登录,您将返回登录状态而无需外部cookie.

在遇到错误之后,在重新启动IIS之前,它不会将cookie分发给任何新会话.

更新2:看起来它与设置Session变量有关.

在removeLogin操作中,我向会话添加了一个值.我不确定为什么,但当我停止这样做时,我就停止了我的问题.时间弄清楚为什么……更新3:看起来这个问题已经是reported to the Katana Team了

更新4:看起来其他人已遇到此问题. Stackoverflow post.他们没有提供解决它所需的所有代码,因此我将在此处作为答案.

Startup.Auth.cs

public void ConfigureAuth(IAppBuilder app) {

    // Configure the db context,user manager and signin manager to use a single instance per request
    app.CreatePerOwinContext(appContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
    app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

    // Enable the application to use a cookie to store information for the signed in user
    // and to use a cookie to temporarily store information about a user logging in with a third party login provider
    // Configure the sign in cookie
    app.UseCookieAuthentication(new CookieAuthenticationOptions {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,AuthenticationMode = AuthenticationMode.Active,LoginPath = new PathString("/Login"),LogoutPath = new PathString("/Logout"),Provider = new CookieAuthenticationProvider {
            // Enables the application to validate the security stamp when the user logs in.
            // This is a security feature which is used when you change a password or add an external login to your account.  
            OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager,User,int>(
                validateInterval: TimeSpan.FromMinutes(30),regenerateIdentityCallback: (manager,user) => user.GenerateUserIdentityAsync(manager),getUserIdCallback: (id) => (Int32.Parse(id.GetUserId()))
            )
        }
    });
    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

    // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
    app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie,TimeSpan.FromMinutes(5));

    // Enables the application to remember the second login verification factor such as phone or email.
    // Once you check this option,your second step of verification during the login process will be remembered on the device where you logged in from.
    // This is similar to the RememberMe option when you log in.
    app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

    // Uncomment the following lines to enable logging in with third party login providers
    app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions{
        ClientId = ConfigurationManager.AppSettings["MSA:Id"],ClientSecret = ConfigurationManager.AppSettings["MSA:Secret"],Caption = "Microsoft"
    });

    app.UseVisualStudioAuthentication(new VisualStudioAuthenticationOptions(){
        AppId = ConfigurationManager.AppSettings["VSO:Id"],AppSecret = ConfigurationManager.AppSettings["VSO:Secret"],Provider = new VisualStudioAuthenticationProvider(){
            OnAuthenticated = (context) =>{
                context.Identity.AddClaim(new Claim("urn:vso:access_token",context.AccessToken,XmlSchemaString,"VisualStudio"));
                context.Identity.AddClaim(new Claim("urn:vso:refresh_token",context.RefreshToken,"VisualStudio"));
                return Task.FromResult(0);
            }
        },Caption = "Visual Studio"
    });

    app.UseGitHubAuthentication(new GitHubAuthenticationOptions{
        ClientId = ConfigurationManager.AppSettings["GH:Id"],ClientSecret = ConfigurationManager.AppSettings["GH:Secret"],Caption = "Github"
    });

    app.UseLinkedInAuthentication(new LinkedInAuthenticationOptions {
        ClientId = ConfigurationManager.AppSettings["LI:Id"],ClientSecret = ConfigurationManager.AppSettings["LI:Secret"],Caption = "LinkedIn"
    });
}

解决方法

OWIN和asp.net以不同方式处理cookie / session.如果在初始化会话之前使用OWIN进行授权,则初始化会话后的任何人都将无法登录.

解决方法:将以下内容添加到Global.asax

// Fix for OWIN session bug
    protected void Application_AcquireRequestState() {
        Session["Workaround"] = 0;
    }
}

长期:OWIN和asp.net处理会话/ cookie的方式将在vNext中合并,使用工作直到那时……

关于作者: dawei

【声明】:金华站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

热门文章