繁体   English   中英

通过OpenId Connect身份验证传递查询字符串参数

[英]Pass query string parameter through OpenId Connect authentication

让我用一点结构来解决问题。

上下文

我们使用Web窗体构建Web应用程序,并托管在Azure Web App中,该应用程序使用OWIN + OpenId Connect标准针对Azure Active Directory对用户进行身份验证。

身份验证过程就像一个魅力,用户可以毫无问题地访问应用程序。

那么,问题是什么?

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

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

编码

启动类看起来像这样:

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。 还尝试将查询字符串参数存储在其他位置,但在此过程的早期无法访问Session。

有谁知道我做错了什么? 或者我只是要求一些不可能的东西? 任何帮助,将不胜感激。

非常感谢你提前!

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

我有两个验证过滤器...

  1. 第一个过滤器应用于所有可能在授权之前使用查询字符串参数命中的控制器。 它检查主体是否经过身份验证。 如果为false,则将完整的url字符串缓存在cookie中。 如果为true,它会查找存在的任何cookie并清除它们,仅用于清理。
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)
        {

        }

    }
  1. 第二个过滤器仅应用于默认登录页面,或者换句话说,标识服务器在登录后重定向。 第二个过滤器查找cookie,如果存在,则调用cookie值的response.Redirect。
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)
        {
        }

    }

暂无
暂无

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

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