【问题标题】:Pass query string parameter through OpenId Connect authentication通过 OpenId Connect 身份验证传递查询字符串参数
【发布时间】:2016-04-27 09:14:01
【问题描述】:

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

上下文

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

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

那么,问题出在哪里?

在苦苦挣扎了很多天之后,我无法通过身份验证过程将任何查询字符串参数传递给应用程序。例如,如果我第一次尝试通过 URL 访问应用程序:https://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 通知的覆盖,我可以访问原始请求网址:

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。

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

非常感谢您!

【问题讨论】:

    标签: c# asp.net azure authentication owin


    【解决方案1】:

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

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

    1. 第一个过滤器应用于所有可能在授权之前被查询字符串参数命中的控制器。它检查主体是否经过身份验证。如果为 false,它会将完整的 url 字符串缓存在 cookie 中。如果为 true,它会查找存在的任何 cookie 并清除它们,仅用于清理。
    公共类 AuthCheckActionFilter : ActionFilterAttribute, IAuthenticationFilter
        {
            公共无效 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);
    
                }
                别的
                {
                    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);
                    }
                }
            }
    
            公共无效 OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
            {
    
            }
    
        }
    
    1. 第二个过滤器仅适用于默认登录页面,即身份服务器在登录后重定向的地方。第二个过滤器查找 cookie,如果存在,它会调用 response.Redirect cookie 值。
    公共类 AutoRedirectFilter : ActionFilterAttribute, IAuthenticationFilter { 公共无效 OnAuthentication(AuthenticationContext filterContext) { 如果(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); } } } 公共无效 OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) { } }

    【讨论】:

      猜你喜欢
      • 2018-04-12
      • 1970-01-01
      • 2014-07-15
      • 2014-02-17
      • 2021-09-07
      • 2014-09-10
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      相关资源
      最近更新 更多