繁体   English   中英

ASP.NET OWIN OpenID Connect 未创建用户身份验证

[英]ASP.NET OWIN OpenID Connect not creating user authentication

我有一个 ASP.NET 4.6 web 应用程序,我正在尝试使用 OWIN 添加 OpenId Connect。

我添加了我的 Owin 启动 class 并且一切似乎都配置正确,但我遇到的问题是 ASP 身份/身份验证用户永远不会被创建。 我最终陷入了一个无限循环,其中 OpenId 回调页面重定向回原始页面,然后重定向到登录页面等。

这是我的启动 class:

public void Configuration(IAppBuilder app)
    {


     app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);


        app.UseKentorOwinCookieSaver();
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Login.aspx"),
            ExpireTimeSpan = TimeSpan.FromDays(7)
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {                
            ClientId = _clientId,
            ClientSecret = _clientSecret,
            Authority = _authority,
            RedirectUri = _redirectUri, // LoginCallback
            PostLogoutRedirectUri = "http://localhost:60624/Logout.aspx",

            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            Scope = "openid profile email",

            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name"
            },

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n =>
                {
                    // Exchange code for access and ID tokens
                    var tokenClient = new TokenClient($"{_authority}/as/token.oauth2", _clientId, _clientSecret);

                    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, _redirectUri);
                    if (tokenResponse.IsError)
                    {
                        throw new Exception(tokenResponse.Error);
                    }

                    var userInfoClient = new UserInfoClient($"{_authority}/idp/userinfo.openid");
                    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

                    var claims = new List<Claim>(userInfoResponse.Claims)
                      {
                        new Claim("id_token", tokenResponse.IdentityToken),
                        new Claim("access_token", tokenResponse.AccessToken)
                      };

                    n.AuthenticationTicket.Identity.AddClaims(claims);



                    //// create the identity
                    //var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationType);

                    //System.Web.HttpContext.Current.GetOwinContext().Authentication.SignIn(new AuthenticationProperties
                    //{
                    //    IsPersistent = true
                    //}, identity);
                }
            }
        });
    }

这是 Login.aspx 页面:

 protected void Page_Load(object sender, EventArgs e)
    {

        if (!Request.IsAuthenticated)
        {
            HttpContext.Current.GetOwinContext().Authentication.Challenge(
              new AuthenticationProperties { RedirectUri = Request["ReturnUrl"] ?? "Default.aspx" },
              OpenIdConnectAuthenticationDefaults.AuthenticationType);
        }        
    }

页面流程是这样的:

1) 请求: http://localhost:60624/Page.aspx响应:302 - 重定向到 Login.aspx

2) 请求: http://localhost:60624/Login.aspx?ReturnUrl=%2FPage.aspx响应 302 - 重定向到https://auth.myprovider.Z2ECD5036D9A2DDA40B

一些 cookies 在响应标头上设置:

设置 Cookie:OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D=xxxxxxxxx; 路径=/; 过期=格林威治标准时间 2019 年 4 月 22 日星期一 14:12:00; HttpOnly 设置 Cookie:OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D=yyyyyyyyy; 过期=格林威治标准时间 2019 年 4 月 22 日星期一 14:12:00; 路径=/; HttpOnly

3) Auth 提供者,登录,它 302 重定向到 /LoginCallback

4) 请求: http://localhost:60624/LoginCallback响应 302 - 重定向到 /Page.aspx

在步骤 2 中设置的 Cookies 在此处被清除。

设置 Cookie:OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D=; 路径=/; expires=Thu, 01-Jan-1970 00:00:00 GMT Set-Cookie: OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D=; 过期=周四,1970 年 1 月 1 日 00:00:00 GMT; 路径=/

5)返回Page.aspx,用户未通过身份验证; 转到第 1 步

我已经进行了一些调试,并且 AuthorizationCodeReceived 在 Startup 上触发,并且后端成功调用了 User Info 端点。 我试图从该通知中调用 System.Web.HttpContext.Current.GetOwinContext().Authentication.SignIn() ,但这似乎没有任何作用。

在这一点上,我被困住了。 为什么未设置用户身份的身份验证 cookie? 似乎这应该自动发生。 我应该自己手动创建吗? 如何手动创建身份验证 cookie 而不是默认方法?

编辑:在查看 @ Zaxxon的回复后,我能够让它工作。 AuthorizationCodeReceived 通知中有两处错误

  1. 我需要创建 ClaimsIdentity。 在我上面提交的原始代码中,我已经注释掉了这一点,但这也是不正确的。
  2. 我不得不用我刚刚创建的新身份替换 AuthenticationTicket。 然后将声明添加到这个新身份。

这是工作代码:

ClaimsIdentity identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.GivenName, ClaimTypes.Role);
 n.AuthenticationTicket = new AuthenticationTicket(identity, n.AuthenticationTicket.Properties);
 n.AuthenticationTicket.Identity.AddClaims(claims);

我有一个ASP.NET 4.6 Web应用程序,我正在尝试使用OWIN添加OpenId Connect。

我添加了Owin启动类,并且所有东西似乎都配置正确,但是我遇到的问题是从未创建过ASP Identity / Authenticated用户。 我最终遇到了一个无限循环,在该循环中,OpenId回调页面重定向回原始页面,然后重定向到原始页面,依此类推。

这是我的入门班:

public void Configuration(IAppBuilder app)
    {


     app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);


        app.UseKentorOwinCookieSaver();
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Login.aspx"),
            ExpireTimeSpan = TimeSpan.FromDays(7)
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {                
            ClientId = _clientId,
            ClientSecret = _clientSecret,
            Authority = _authority,
            RedirectUri = _redirectUri, // LoginCallback
            PostLogoutRedirectUri = "http://localhost:60624/Logout.aspx",

            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            Scope = "openid profile email",

            TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name"
            },

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                AuthorizationCodeReceived = async n =>
                {
                    // Exchange code for access and ID tokens
                    var tokenClient = new TokenClient($"{_authority}/as/token.oauth2", _clientId, _clientSecret);

                    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, _redirectUri);
                    if (tokenResponse.IsError)
                    {
                        throw new Exception(tokenResponse.Error);
                    }

                    var userInfoClient = new UserInfoClient($"{_authority}/idp/userinfo.openid");
                    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

                    var claims = new List<Claim>(userInfoResponse.Claims)
                      {
                        new Claim("id_token", tokenResponse.IdentityToken),
                        new Claim("access_token", tokenResponse.AccessToken)
                      };

                    n.AuthenticationTicket.Identity.AddClaims(claims);



                    //// create the identity
                    //var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationType);

                    //System.Web.HttpContext.Current.GetOwinContext().Authentication.SignIn(new AuthenticationProperties
                    //{
                    //    IsPersistent = true
                    //}, identity);
                }
            }
        });
    }

这是Login.aspx页面:

 protected void Page_Load(object sender, EventArgs e)
    {

        if (!Request.IsAuthenticated)
        {
            HttpContext.Current.GetOwinContext().Authentication.Challenge(
              new AuthenticationProperties { RedirectUri = Request["ReturnUrl"] ?? "Default.aspx" },
              OpenIdConnectAuthenticationDefaults.AuthenticationType);
        }        
    }

页面流如下所示:

1)请求: http:// localhost:60624 / Page.aspx响应:302-重定向到Login.aspx

2)请求: http:// localhost:60624 / Login.aspx?ReturnUrl =%2FPage.aspx响应302-重定向到https://auth.myprovider.com

此处在响应标头上设置了一些cookie:

设置Cookie:OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D = xxxxxxxxx; 路径= /; expires =星期一,2019年4月22日14:12:00 GMT; HttpOnly Set-Cookie:OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D = yyyyyyyyy; expires =星期一,2019年4月22日14:12:00 GMT; 路径= /; HttpOnly

3)身份验证提供程序,登录,并将其重定向到/ LoginCallback 302

4)请求: http:// localhost:60624 / LoginCallback响应302-重定向到/Page.aspx

在此清除在步骤2中设置的Cookie。

设置Cookie:OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D =; 路径= /; expires =星期四,1970年1月1日00:00:00 GMT Set-Cookie:OpenIdConnect.nonce.KIsuj4RUmGKJIynLrkEScxBvGrZzkMo6ylZ%2F4lRknPM%3D =; expires =星期四,格林尼治标准时间1970年1月1日00:00:00; 路径= /

5)返回Page.aspx,用户未通过身份验证; 转到步骤1

我已经进行了一些调试,并且在启动时触发了AuthorizationCodeReceived,并且后端成功调用了User Info端点。 我试图从该Notification中调用System.Web.HttpContext.Current.GetOwinContext()。Authentication.SignIn(),但这似乎无济于事。

在这一点上,我被困住了。 为什么未设置用于用户身份的身份验证cookie? 看来这应该是自动发生的。 我应该自己手动创建这个吗? 如何手动创建身份验证cookie而不是默认方法?

编辑:在审查@ Zaxxon的答复后,我能够使其工作。 AuthorizationCodeReceived通知中有两处错误

  1. 我需要创建ClaimsIdentity。 在上面提交的原始代码中,我已经对此进行了注释,但这也是不正确的。
  2. 我必须用刚刚创建的新身份用新的AuthenticationTicket替换。 然后将声明添加到此新标识中。

这是工作代码:

ClaimsIdentity identity = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.GivenName, ClaimTypes.Role);
 n.AuthenticationTicket = new AuthenticationTicket(identity, n.AuthenticationTicket.Properties);
 n.AuthenticationTicket.Identity.AddClaims(claims);

我遇到了您提到的关于Cookie的相同问题。 即使我已经尝试过您的代码也不起作用(它与登录uri不断循环)。 实际问题是我没有获取访问令牌和ID令牌,AuthorizationCodeReceived处理授权码流和userinfoclient。

当我们传递授权代码流参数(clientid,ClientSecret,代码,redirecturi)时,它返回访问令牌和id令牌,请求正在进行,但我没有得到任何响应。

提前致谢!。

就我而言,我根本不需要在启动文件中的Notifications中添加任何内容。 我错过了这个:

app.UseCookieAuthentication(new CookieAuthenticationOptions() 
{
    CookieManager = new SystemWebCookieManager()
});

Katana 中有一些错误会阻止 cookies 正确保存,因此添加这行代码在三天后解决了我的问题!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM