C# 通过OpenId连接身份验证传递查询字符串参数

C# 通过OpenId连接身份验证传递查询字符串参数,c#,asp.net,azure,authentication,owin,C#,Asp.net,Azure,Authentication,Owin,让我用一点结构来解释这个问题 上下文 我们有一个使用web表单构建的web应用程序,托管在Azure web应用程序中,该应用程序使用OWIN+OpenId Connect标准根据Azure Active Directory对用户进行身份验证 认证过程就像一个魔咒,用户可以毫无问题地访问应用程序 那么,问题是什么? 经过几天的努力,我无法通过身份验证过程将任何查询字符串参数传递给应用程序。例如,如果我第一次尝试通过URL访问应用程序:https://myapp.azurewebsites.net

让我用一点结构来解释这个问题

上下文 我们有一个使用web表单构建的web应用程序,托管在Azure web应用程序中,该应用程序使用OWIN+OpenId Connect标准根据Azure Active Directory对用户进行身份验证

认证过程就像一个魔咒,用户可以毫无问题地访问应用程序

那么,问题是什么? 经过几天的努力,我无法通过身份验证过程将任何查询字符串参数传递给应用程序。例如,如果我第一次尝试通过URL访问应用程序:
https://myapp.azurewebsites.net/Default.aspx?param=value
。我需要传递此参数的原因是它会触发主页中的某些特定操作

问题是,身份验证重定向到webapp主页后,请求的原始查询字符串参数就消失了

代码 startup类如下所示:

app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = Constants.ADTenant.ClientId,
                    Authority = Constants.ADTenant.Authority,
                    PostLogoutRedirectUri = Constants.ADTenant.PostLogoutRedirectUri,

                    Notifications = new OpenIdConnectAuthenticationNotifications
                    {
                        AuthorizationCodeReceived = context =>
                        {
                            var code = context.Code;

                            ClientCredential credential = new ClientCredential(Constants.ADTenant.ClientId,
                                Constants.ADTenant.AppKey);
                            string userObjectID = context.AuthenticationTicket.Identity.FindFirst(
                                Constants.ADTenant.ObjectIdClaimType).Value;
                            AuthenticationContext authContext = new AuthenticationContext(Constants.ADTenant.Authority,
                                new NaiveSessionCache(userObjectID));
                            if (HttpContext.Current != null)
                            {
                                AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                                    code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential,
                                    Constants.ADTenant.GraphResourceId);
                                AuthenticationHelper.token = result.AccessToken;
                                AuthenticationHelper.refreshToken = result.RefreshToken;
                            }
                            return Task.FromResult(0);
                        }
                    }
                });
而且它工作正常

我已经试过了 通过添加对
RedirectToIdentityProvider
通知的覆盖,我可以访问原始请求Url:

RedirectToIdentityProvider = (context) =>
                        {
                            // Ensure the URI is picked up dynamically from the request;
                            string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Uri.PathAndQuery;
                            context.ProtocolMessage.RedirectUri = appBaseUrl;
                            return Task.FromResult(0);
                        }
通过这种方式,我试图强制重定向到主页面,包括原始的查询字符串参数,但随后身份验证后的重定向中断,陷入无限循环

我还尝试过在Azure AD中更改应用程序配置的重定向url,但没有成功。还尝试将查询字符串参数存储在其他位置,但在进程的早期无法访问会话

有人知道我做错了什么吗?或者我只是在要求一些不可能的事情?任何帮助都将不胜感激


提前非常感谢

我最近也需要做同样的事情。我的解决方案可能不是最复杂的,但简单也不总是坏事

我有两个身份验证筛选器…

  • 第一个过滤器应用于所有可能在授权之前被查询字符串参数击中的控制器。它检查主体是否经过身份验证。如果为false,则在cookie中缓存完整的url字符串。如果为true,则查找存在的任何cookie并将其清除,仅用于清理
  • 公共类AuthCheckActionFilter:ActionFilterAttribute,IAAuthenticationFilter { 身份验证时的公共无效(AuthenticationContext filterContext) { 如果(!filterContext.Principal.Identity.IsAuthenticated) { HttpCookie cookie=新的HttpCookie(“OnAuthenticateAction”); cookie.Value=filterContext.HttpContext.Request.Url.OriginalString; filterContext.HttpContext.Response.Cookies.Add(cookie); } 其他的 { if(filterContext.HttpContext.Request.Cookies.AllKeys.Contains(“OnAuthenticationAction”)) { HttpCookie cookie=filterContext.HttpContext.Request.Cookies[“OnAuthenticateAction”]; cookie.Expires=DateTime.Now.AddDays(-1); filterContext.HttpContext.Response.Cookies.Add(cookie); } } } AuthenticationChallenge上的公共无效(AuthenticationChallengeContext筛选器上下文) { } }
  • 第二个筛选器仅应用于默认登录页,或者换句话说,在登录后identity server正在重定向的情况下。第二个筛选器查找cookie,如果它存在,则调用response.Redirect on cookie值
  • 公共类AutoRedirectFilter:ActionFilterAttribute、IAAuthenticationFilter { 身份验证时的公共无效(AuthenticationContext filterContext) { if(filterContext.Principal.Identity.IsAuthenticated) { if(filterContext.HttpContext.Request.Cookies.AllKeys.Contains(“OnAuthenticationAction”)) { HttpCookie cookie=filterContext.HttpContext.Request.Cookies[“OnAuthenticateAction”]; filterContext.HttpContext.Response.Redirect(cookie.Value); } } } AuthenticationChallenge上的公共无效(AuthenticationChallengeContext筛选器上下文) { } }
    我最近也需要做同样的事情。我的解决方案可能不是最复杂的,但简单也不总是坏事

    我有两个身份验证筛选器…

  • 第一个过滤器应用于所有可能在授权之前被查询字符串参数击中的控制器。它检查主体是否经过身份验证。如果为false,则在cookie中缓存完整的url字符串。如果为true,则查找存在的任何cookie并将其清除,仅用于清理
  • 公共类AuthCheckActionFilter:ActionFilterAttribute,IAAuthenticationFilter { 身份验证时的公共无效(AuthenticationContext filterContext) { 如果(!filterContext.Principal.Identity.IsAuthenticated) { HttpCookie cookie=新的HttpCookie(“OnAuthenticateAction”); cookie.Value=filterContext.HttpContext.Request.Url.OriginalString; filterContext.HttpContext.Response.Cookies.Add(cookie); } 其他的 { if(filterContext.HttpContext.Request.Cookies.AllKeys.Contains(“OnAuthenticationAction”)) { HttpCookie cookie=filterContext.HttpContext.Request.Cookies[“OnAuthenticateAction”]; cookie.Expires=DateTime.Now.AddDays(-1); filterContext.HttpContext.Response.Cookies.Add(cookie); } } } AuthenticationChallenge上的公共无效(AuthenticationChallengeContext筛选器上下文) { } }
  • 第二个过滤器是appli public class AuthCheckActionFilter : ActionFilterAttribute, IAuthenticationFilter { public void OnAuthentication(AuthenticationContext filterContext) { if (!filterContext.Principal.Identity.IsAuthenticated) { HttpCookie cookie = new HttpCookie("OnAuthenticateAction"); cookie.Value = filterContext.HttpContext.Request.Url.OriginalString; filterContext.HttpContext.Response.Cookies.Add(cookie); } else { if (filterContext.HttpContext.Request.Cookies.AllKeys.Contains("OnAuthenticateAction")) { HttpCookie cookie = filterContext.HttpContext.Request.Cookies["OnAuthenticateAction"]; cookie.Expires = DateTime.Now.AddDays(-1); filterContext.HttpContext.Response.Cookies.Add(cookie); } } } public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) { } } public class AutoRedirectFilter : ActionFilterAttribute, IAuthenticationFilter { public void OnAuthentication(AuthenticationContext filterContext) { if(filterContext.Principal.Identity.IsAuthenticated) { if(filterContext.HttpContext.Request.Cookies.AllKeys.Contains("OnAuthenticateAction")) { HttpCookie cookie = filterContext.HttpContext.Request.Cookies["OnAuthenticateAction"]; filterContext.HttpContext.Response.Redirect(cookie.Value); } } } public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) { } }