.net 从未发布OpenIDConnectAuthenticationCookie

.net 从未发布OpenIDConnectAuthenticationCookie,.net,asp.net-mvc,owin,openid-connect,okta,.net,Asp.net Mvc,Owin,Openid Connect,Okta,我们有一个.net MVC web应用程序,它使用ASP.net成员身份进行用户身份验证。我们还为我们的移动应用程序发行不记名代币。我试图以okta为例添加对SSO的支持。我已经在Okta中创建了一个应用程序,正在尝试登录我们的应用程序。我目前的流程如下: 打开登录页面 点击“使用okta登录” 我们的服务器收到请求。用户未通过身份验证,因此发出质询 用户被重定向到Okta的登录页面 成功登录后,会向登录重定向url发出请求(我想这是由OpenIdConnect中间件捕获的?) 将触发Autho

我们有一个.net MVC web应用程序,它使用ASP.net成员身份进行用户身份验证。我们还为我们的移动应用程序发行不记名代币。我试图以okta为例添加对SSO的支持。我已经在Okta中创建了一个应用程序,正在尝试登录我们的应用程序。我目前的流程如下:

  • 打开登录页面
  • 点击“使用okta登录”
  • 我们的服务器收到请求。用户未通过身份验证,因此发出质询
  • 用户被重定向到Okta的登录页面
  • 成功登录后,会向登录重定向url发出请求(我想这是由OpenIdConnect中间件捕获的?)
  • 将触发AuthorizationCodeReceived事件
  • 重定向完成,但未发出cookie
  • 用户被重定向到登录页面,但由于他们没有经过身份验证,因此会重定向到Okta进行登录。循环回到步骤4并重复
  • 似乎在登录重定向和我设置了正确的声明之后,结果应该是在响应中发出并返回一个cookie,以表示用户已登录。我不确定我在这里遗漏了什么,但如果有人能给我指出正确的方向,或解释正在发生的事情,我将非常感激

    下面是Startup.cs中的一个片段:

    public void ConfigureAuth(IAppBuilder app, bool allowInsecureHttp = false)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(OwinIdentityDbContext.Create);
        app.CreatePerOwinContext<IdentityUserManager>(IdentityUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    
        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            ClientId = GlobalConstants.Settings.OktaClientId,
            ClientSecret = GlobalConstants.Settings.OktaClientSecret,
            Authority = GlobalConstants.Settings.OktaDomain,
            AuthenticationType = "okta", // This is basically a "name" for this open id configuration
            RedirectUri = GlobalConstants.Settings.OktaRedirectUri,
            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            Scope = $"{OpenIdConnectScope.OpenIdProfile} {OpenIdConnectScope.Email}", // Get the profile and email
            PostLogoutRedirectUri = GlobalConstants.Settings.OktaPostLogoutRedirectUri,
            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name"
            },
    
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n =>
                {
                    // Exchange code for access and ID tokens
                    var tokenClient = new TokenClient(GlobalConstants.Settings.OktaDomain + "/v1/token", GlobalConstants.Settings.OktaClientId, GlobalConstants.Settings.OktaClientSecret);
                    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, GlobalConstants.Settings.OktaRedirectUri);
    
                    if (tokenResponse.IsError)
                    {
                        throw new Exception(tokenResponse.Error);
                    }
    
                    var userInfoClient = new UserInfoClient(GlobalConstants.Settings.OktaDomain + "/v1/userinfo");
                    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);
                    var claims = new List<Claim>();
                    claims.AddRange(userInfoResponse.Claims);
                    claims.Add(new Claim("id_token", tokenResponse.IdentityToken));
                    claims.Add(new Claim("access_token", tokenResponse.AccessToken));
    
                    if (!string.IsNullOrEmpty(tokenResponse.RefreshToken))
                    {
                        claims.Add(new Claim("refresh_token", tokenResponse.RefreshToken));
                    }
    
                    // Add custom user claims here
                    #region Add custom claims
    
                    var email = claims.Find(_ => _.Type == "email")?.Value;
    
                    claims.Add(new Claim(ClaimTypes.Name, email));
                    claims.Add(new Claim(ClaimTypes.NameIdentifier, email));
    
                    // Hardcoded for now. Discover these for real later
                    claims.Add(new Claim(CustomClaimTypes.OurUserId, "{userId}"));
                    claims.Add(new Claim(CustomClaimTypes.OurOrganizationId, "{orgId}"));
    
                    #endregion
    
                    // https://stackoverflow.com/questions/55797063/asp-net-owin-openid-connect-not-creating-user-authentication
                    var identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);
                    n.AuthenticationTicket = new AuthenticationTicket(identity, n.AuthenticationTicket.Properties);
                    n.AuthenticationTicket.Identity.AddClaims(claims);
    
                    return;
                },
    
                RedirectToIdentityProvider = n =>
                {
                    // If signing out, add the id_token_hint
                    if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                    {
                        var idTokenClaim = n.OwinContext.Authentication.User.FindFirst("id_token");
    
                        if (idTokenClaim != null)
                        {
                            n.ProtocolMessage.IdTokenHint = idTokenClaim.Value;
                        }
                    }
    
                    return Task.CompletedTask;
                }
            },
        });
    
        app.UseCookieAuthentication(
            new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                CookieManager = new SystemWebCookieManager(),
                LoginPath = new PathString("/"),
                SlidingExpiration = true,
                CookieSecure = GlobalConstants.Settings.IsEnvironmentDev ? CookieSecureOption.SameAsRequest : CookieSecureOption.Always,
                Provider = new CookieAuthenticationProvider
                {
                    OnApplyRedirect = context =>
                    {
                        if (IsClientPortalRequest(context.Request))
                        {
                            context.Response.Redirect("/public/ClientPortalLogin");
                        }
                        else if (!IsAjaxRequest(context.Request) && !IsPublicApiRequest(context.Request) && !IsWopiRequest(context.Request))
                        {
                            context.Response.Redirect(context.RedirectUri);
                        }
                    }
                }
            });
    
        // For Two Factor Log In
        app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(10));
    
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = allowInsecureHttp, // NOTE: Only for unit tests
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new CustomBearerTokenProvider()
        };
    
        // Configure Bearer Token Generation
        app.UseOAuthAuthorizationServer(OAuthOptions);
    
        // Needed to Authenticate Bearer Tokens
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    
        // Set Cookies are the default type
        app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ApplicationCookie);
    }
    
    public void ConfigureAuth(IAppBuilder应用程序,bool allowInsecureHttp=false)
    {
    //将数据库上下文、用户管理器和登录管理器配置为每个请求使用一个实例
    app.CreatePerOwinContext(OwinIdentityDbContext.Create);
    app.CreatePerOwinContext(IdentityUserManager.Create);
    
    app.CreatePerOwinContext

    我也有同样的问题,这是我发现的。问题不在我的连接代码中,而是在我的控制器类中。我的控制器操作上有一个属性,要求用户扮演某些角色。这最终是导致重定向循环的原因

    如果你有,你需要摆脱它,找到一种不同的方式来处理角色

    这显示了有问题的代码:

    以下是引起我“啊哈”时刻的文章链接:


    希望这对其他人有所帮助,我花了太长时间才弄明白这一点。

    服务器是否正在创建一个身份验证cookie并保存在浏览器上?您可以使用浏览器中的开发工具查看它吗?当我检查响应的cookie时,有一个cookie的名称为“OpenIdConnect.nonce.lmY6ycbG52f%2BQeGNuvsb32vwVZnKZSPVof0xJ7VE%2FgY%3D”这是请求cookie的名称,值为blank@chronolinq你解决过这个问题吗?我正在更新一个旧版的ASPNET MVC 5应用程序以使用OpenIdConnect,并且具有完全相同的症状-auth可以工作,但它重定向到主控制器,而没有设置ApplicationOkie,因此重定向回Idp登录页,对strai进行身份验证马上,重定向回主页等-我不知道为什么没有设置ApplicationOkie,OpenIdConnect.nonce和OpenIdConnect.nv cookies是在身份验证过程中设置的,并在/signin oidc(OpenIdConnect中间件必须处理的)主页重定向时清除-非常希望听到您的消息:)