简体   繁体   English

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

[英]Pass query string parameter through OpenId Connect authentication

Let me put the problem with a bit of structure. 让我用一点结构来解决问题。

Context 上下文

We have a web application build with Web Forms and hosted in an Azure Web App that authenticates the users against an Azure Active Directory using the OWIN + OpenId Connect standards. 我们使用Web窗体构建Web应用程序,并托管在Azure Web App中,该应用程序使用OWIN + OpenId Connect标准针对Azure Active Directory对用户进行身份验证。

The authentication process works like a charm and users are able to access the application without any problem. 身份验证过程就像一个魅力,用户可以毫无问题地访问应用程序。

So, whats the issue? 那么,问题是什么?

After struggling for many days with it I'm unable to pass any query string parameter to the application through the authentication process. 经过多天的努力,我无法通过身份验证过程将任何查询字符串参数传递给应用程序。 For example, if I try to access the application for the first time through the URL: https://myapp.azurewebsites.net/Default.aspx?param=value . 例如,如果我第一次尝试通过URL访问应用程序: https://myapp.azurewebsites.net/Default.aspx?param=valuehttps://myapp.azurewebsites.net/Default.aspx?param=value The reason I need to pass this parameter is that it triggers some specific actions in the main page. 我需要传递此参数的原因是它会触发主页面中的某些特定操作。

The problem is that after the authentication redirects to the webapp's main page the original query string parameters of the request are gone. 问题是在身份验证重定向到webapp的主页面后,请求的原始查询字符串参数消失了。

The code 编码

The startup class looks like this: 启动类看起来像这样:

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);
                        }
                    }
                });

And it works properly! 它运作正常!

What I already tried 我已经尝试过了什么

I've got access to the original request Url by adding an overwrite of the RedirectToIdentityProvider notification: 通过添加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);
                        }

With this I tried to force the redirect to the main page including the original query string parameter, but then the redirection after authentication breaks and gets stuck in an infinite loop. 有了这个,我试图强制重定向到主页面,包括原始查询字符串参数,但随后身份验证中断后的重定向并陷入无限循环。

I've also tried with changing the redirect url of the application configuration in Azure AD without luck. 我也试过在没有运气的情况下更改Azure AD中应用程序配置的重定向URL。 Also tried to store the query string parameters somewhere else, but the Session is not accessible that early in the process. 还尝试将查询字符串参数存储在其他位置,但在此过程的早期无法访问Session。

Does anyone know what am I doing wrong? 有谁知道我做错了什么? Or I'm just asking for something impossible? 或者我只是要求一些不可能的东西? Any help would be appreciated. 任何帮助,将不胜感激。

Thank you very much in advance! 非常感谢你提前!

I recently had a need to do the exact same thing. 我最近需要做同样的事情。 My solution may not be the most sophisticated, but simple isn't always bad either. 我的解决方案可能不是最复杂的,但简单并不总是坏的。

I have two Authentication Filters... 我有两个验证过滤器...

  1. The first filter is applied to all controllers that could potentially be hit with query string parameters prior to authorization. 第一个过滤器应用于所有可能在授权之前使用查询字符串参数命中的控制器。 It checks if the principal is authenticated. 它检查主体是否经过身份验证。 If false it caches the complete url string in a cookie. 如果为false,则将完整的url字符串缓存在cookie中。 If true it looks for any cookies present and clears them, just for cleanup. 如果为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. The second filter is applied only to the default landing page, or in other words where the identity server is redirecting after login. 第二个过滤器仅应用于默认登录页面,或者换句话说,标识服务器在登录后重定向。 This second filter looks for a cookie and if it exists it calls response.Redirect on cookie value. 第二个过滤器查找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.

相关问题 OpenId Connect身份验证.NET Core - OpenId Connect Authentication .NET Core OpenID 连接身份验证中的 ValidateIssuer 选项 - ValidateIssuer option in OpenID connect authentication OpenID Connect 身份验证成功。 怎么办? - OpenID Connect Authentication Successful. Now what? .Net Core 2 OpenID Connect身份验证和多个身份 - .Net Core 2 OpenID Connect Authentication and multiple Identities 将字符串变量作为查询参数传递给LINQ查询 - Pass string variable as query parameter to LINQ query 通过控制器将身份生成的ID传递给视图中的下一页作为查询字符串参数 - Pass identity generated ID to the next page in view as query string parameter through controller 如何在MVC中将URL作为查询字符串参数传递 - How to pass a URL as a query string parameter in MVC 如何将带有查询字符串的 url 作为 api 参数传递? - How to pass url with query string as an api parameter? 如何通过查询字符串传递异常对象 - How to pass exception object through query string 是否可以获取查询字符串参数列表并更改参数1并作为参数传递 - Is it possible to get list of query string parameters and change 1 of the parameter and pass as parameter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM