예제 #1
0
        protected virtual string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
        {
            var scopeParameter = properties.GetParameter <ICollection <string> >(OAuthChallengeProperties.ScopeKey);
            var scope          = scopeParameter != null?FormatScope(scopeParameter) : FormatScope();

            var parameters = new Dictionary <string, string>
            {
                { "client_id", Options.ClientId },
                { "scope", scope },
                { "response_type", "code" },
                { "redirect_uri", redirectUri },
            };

            if (Options.UsePkce)
            {
                var bytes = new byte[32];
                CryptoRandom.GetBytes(bytes);
                var codeVerifier = Base64UrlTextEncoder.Encode(bytes);

                // Store this for use during the code redemption.
                properties.Items.Add(OAuthConstants.CodeVerifierKey, codeVerifier);

                using var sha256 = SHA256.Create();
                var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
                var codeChallenge  = WebEncoders.Base64UrlEncode(challengeBytes);

                parameters[OAuthConstants.CodeChallengeKey]       = codeChallenge;
                parameters[OAuthConstants.CodeChallengeMethodKey] = OAuthConstants.CodeChallengeMethodS256;
            }

            parameters["state"] = Options.StateDataFormat.Protect(properties);

            return(QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, parameters));
        }
예제 #2
0
        private void AddQueryString <T>(
            IDictionary <string, string> queryStrings,
            AuthenticationProperties properties,
            string name,
            Func <T, string> formatter,
            T defaultValue)
        {
            string value          = null;
            var    parameterValue = properties.GetParameter <T>(name);

            if (parameterValue != null)
            {
                value = formatter(parameterValue);
            }
            else if (!properties.Items.TryGetValue(name, out value))
            {
                value = formatter(defaultValue);
            }

            // Remove the parameter from AuthenticationProperties so it won't be serialized into the state
            properties.Items.Remove(name);

            if (value != null)
            {
                queryStrings[name] = value;
            }
        }
예제 #3
0
        protected override string BuildChallengeUrl([NotNull] AuthenticationProperties properties, [NotNull] string redirectUri)
        {
            var    scopeParameter = properties.GetParameter <ICollection <string> >(OAuthChallengeProperties.ScopeKey);
            string scopes         = scopeParameter != null?FormatScope(scopeParameter) : FormatScope();

            var parameters = new Dictionary <string, string?>
            {
                ["app_id"]       = Options.ClientId,
                ["redirect_uri"] = redirectUri,
                ["perms"]        = scopes,
            };

            if (Options.UsePkce)
            {
                byte[] bytes = new byte[32];
                RandomNumberGenerator.Fill(bytes);
                string codeVerifier = Microsoft.AspNetCore.WebUtilities.Base64UrlTextEncoder.Encode(bytes);

                // Store this for use during the code redemption.
                properties.Items.Add(OAuthConstants.CodeVerifierKey, codeVerifier);

                byte[] challengeBytes = SHA256.HashData(Encoding.UTF8.GetBytes(codeVerifier));
                parameters[OAuthConstants.CodeChallengeKey]       = WebEncoders.Base64UrlEncode(challengeBytes);
                parameters[OAuthConstants.CodeChallengeMethodKey] = OAuthConstants.CodeChallengeMethodS256;
            }

            parameters["state"] = Options.StateDataFormat.Protect(properties);

            return(QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, parameters));
        }
        public void GetSetParameter_Int()
        {
            var props = new AuthenticationProperties();

            Assert.Null(props.GetParameter <int?>("foo"));
            Assert.Equal(0, props.Parameters.Count);

            props.SetParameter <int?>("foo", 123);
            Assert.Equal(123, props.GetParameter <int?>("foo"));
            Assert.Equal(123, props.Parameters["foo"]);
            Assert.Equal(1, props.Parameters.Count);

            props.SetParameter <int?>("foo", null);
            Assert.Null(props.GetParameter <int?>("foo"));
            Assert.Null(props.Parameters["foo"]);
            Assert.Equal(1, props.Parameters.Count);
        }
        public void GetSetParameter_String()
        {
            var props = new AuthenticationProperties();

            Assert.Null(props.GetParameter <string>("foo"));
            Assert.Equal(0, props.Parameters.Count);

            props.SetParameter <string>("foo", "foo bar");
            Assert.Equal("foo bar", props.GetParameter <string>("foo"));
            Assert.Equal("foo bar", props.Parameters["foo"]);
            Assert.Equal(1, props.Parameters.Count);

            props.SetParameter <string>("foo", null);
            Assert.Null(props.GetParameter <string>("foo"));
            Assert.Null(props.Parameters["foo"]);
            Assert.Equal(1, props.Parameters.Count);
        }
예제 #6
0
        protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
        {
            var queryStrings = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            queryStrings.Add("request_token", properties.GetParameter <string>("RequestToken"));
            queryStrings.Add("redirect_uri", BuildRedirectUri(Options.CallbackPath.Value));
            return(QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings));
        }
예제 #7
0
        /// <summary>
        /// BuildChallengeUrl
        /// </summary>
        protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
        {
            var parameter = properties.GetParameter <ICollection <string> >(OAuthChallengeProperties.ScopeKey);
            var scopes    = parameter != null?FormatScope(parameter) : FormatScope();

            //string siteState = Options.StateDataFormat.Protect(properties);
            string siteState = properties.Items.ContainsKey(RedirectName) ? properties.Items[RedirectName] : "";

            if (!string.IsNullOrEmpty(siteState))
            {
                var encode = WebUtility.UrlEncode(siteState);
                redirectUri += $"?{SiteReturnAdditional}={encode}";
            }

            var timestamp    = GetTimeStamp();
            var state        = GetState();
            var signMessage  = $"{scopes}{timestamp}{Options.ClientId}{state}";
            var clientSecret = SignString(signMessage).Result;
            var res          = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, new Dictionary <string, string>
            {
                {
                    "client_id",
                    Options.ClientId
                },
                {
                    "client_secret",
                    clientSecret
                },
                {
                    "redirect_uri",
                    redirectUri
                },
                {
                    "scope",
                    scopes
                },
                {
                    "response_type",
                    "code"
                },
                {
                    "state",
                    state
                },
                {
                    "access_type",
                    "online"
                },
                {
                    "timestamp",
                    timestamp
                }
            });

            return(res);
        }
        public void GetSetParameter_Collection()
        {
            var props = new AuthenticationProperties();

            Assert.Null(props.GetParameter <int?>("foo"));
            Assert.Equal(0, props.Parameters.Count);

            var list = new string[] { "a", "b", "c" };

            props.SetParameter <ICollection <string> >("foo", list);
            Assert.Equal(new string[] { "a", "b", "c" }, props.GetParameter <ICollection <string> >("foo"));
            Assert.Same(list, props.Parameters["foo"]);
            Assert.Equal(1, props.Parameters.Count);

            props.SetParameter <ICollection <string> >("foo", null);
            Assert.Null(props.GetParameter <ICollection <string> >("foo"));
            Assert.Null(props.Parameters["foo"]);
            Assert.Equal(1, props.Parameters.Count);
        }
        public static AuthToken RetrieveToken(this AuthenticationProperties properties, string tokenName = default)
        {
            if (properties is null)
            {
                throw new ArgumentNullException(nameof(properties));
            }

            var tokenKey = TokenPropertyName(tokenName ?? string.Empty);

            return(properties.Parameters.ContainsKey(tokenKey) ? properties.GetParameter <AuthToken>(tokenKey) : null);
        }
예제 #10
0
    /// <inheritdoc />
    protected override string BuildChallengeUrl([NotNull] AuthenticationProperties properties, [NotNull] string redirectUri)
    {
        if (!properties.Items.TryGetValue(ShopifyAuthenticationDefaults.ShopNameAuthenticationProperty, out var shopName))
        {
            Log.ShopNameMissing(Logger);
            throw new InvalidOperationException("Shopify provider AuthenticationProperties must contain ShopNameAuthenticationProperty.");
        }

        var authorizationEndpoint = string.Format(CultureInfo.InvariantCulture, Options.AuthorizationEndpoint, shopName);

        // Get the permission scope, which can either be set in options or overridden in AuthenticationProperties.
        if (!properties.Items.TryGetValue(ShopifyAuthenticationDefaults.ShopScopeAuthenticationProperty, out var scope))
        {
            var scopeParameter = properties.GetParameter <ICollection <string> >(OAuthChallengeProperties.ScopeKey);
            scope = scopeParameter != null?FormatScope(scopeParameter) : FormatScope();
        }

        var parameters = new Dictionary <string, string?>()
        {
            ["client_id"]    = Options.ClientId,
            ["scope"]        = scope,
            ["redirect_uri"] = redirectUri,
        };

        if (Options.UsePkce)
        {
            var bytes        = RandomNumberGenerator.GetBytes(256 / 8);
            var codeVerifier = WebEncoders.Base64UrlEncode(bytes);

            // Store this for use during the code redemption.
            properties.Items.Add(OAuthConstants.CodeVerifierKey, codeVerifier);

            var challengeBytes = SHA256.HashData(Encoding.UTF8.GetBytes(codeVerifier));
            parameters[OAuthConstants.CodeChallengeKey]       = WebEncoders.Base64UrlEncode(challengeBytes);
            parameters[OAuthConstants.CodeChallengeMethodKey] = OAuthConstants.CodeChallengeMethodS256;
        }

        parameters["state"] = Options.StateDataFormat.Protect(properties);

        var challengeUrl = QueryHelpers.AddQueryString(authorizationEndpoint, parameters);

        // If we're requesting a per-user, online only, token, add the grant_options query param.
        if (properties.Items.TryGetValue(ShopifyAuthenticationDefaults.GrantOptionsAuthenticationProperty, out var grantOptions) &&
            grantOptions == ShopifyAuthenticationDefaults.PerUserAuthenticationPropertyValue)
        {
            challengeUrl = QueryHelpers.AddQueryString(challengeUrl, "grant_options[]", ShopifyAuthenticationDefaults.PerUserAuthenticationPropertyValue);
        }

        return(challengeUrl);
    }
    protected override string BuildChallengeUrl([NotNull] AuthenticationProperties properties, [NotNull] string redirectUri)
    {
        var scopeParameter = properties.GetParameter <ICollection <string> >(OAuthChallengeProperties.ScopeKey);
        var scope          = scopeParameter != null?FormatScope(scopeParameter) : FormatScope();

        var parameters = new Dictionary <string, string?>()
        {
            ["appid"]         = Options.ClientId,
            ["scope"]         = scope,
            ["response_type"] = "code",
        };

        if (Options.UsePkce)
        {
            var bytes        = RandomNumberGenerator.GetBytes(256 / 8);
            var codeVerifier = WebEncoders.Base64UrlEncode(bytes);

            // Store this for use during the code redemption.
            properties.Items.Add(OAuthConstants.CodeVerifierKey, codeVerifier);

            var challengeBytes = SHA256.HashData(Encoding.UTF8.GetBytes(codeVerifier));

            parameters[OAuthConstants.CodeChallengeKey]       = WebEncoders.Base64UrlEncode(challengeBytes);
            parameters[OAuthConstants.CodeChallengeMethodKey] = OAuthConstants.CodeChallengeMethodS256;
        }

        var state           = Options.StateDataFormat.Protect(properties);
        var addRedirectHash = false;

        if (!IsWeixinAuthorizationEndpointInUse())
        {
            // Store state in redirectUri when authorizing Wechat Web pages to prevent "too long state parameters" error
            redirectUri     = QueryHelpers.AddQueryString(redirectUri, OauthState, state);
            addRedirectHash = true;
        }

        parameters["redirect_uri"] = redirectUri;
        parameters[State]          = addRedirectHash ? OauthState : state;

        var challengeUrl = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, parameters);

        if (addRedirectHash)
        {
            // The parameters necessary for Web Authorization of Wechat
            challengeUrl += "#wechat_redirect";
        }

        return(challengeUrl);
    }
예제 #12
0
        protected virtual string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
        {
            var scopeParameter = properties.GetParameter <ICollection <string> >(OAuthChallengeProperties.ScopeKey);
            var scope          = scopeParameter != null?FormatScope(scopeParameter) : FormatScope();

            var state      = Options.StateDataFormat.Protect(properties);
            var parameters = new Dictionary <string, string>
            {
                { "client_id", Options.ClientId },
                { "scope", scope },
                { "response_type", "code" },
                { "redirect_uri", redirectUri },
                { "state", state },
            };

            return(QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, parameters));
        }
예제 #13
0
        private static void AddQueryString <T>(IDictionary <string, string> queryStrings, AuthenticationProperties properties, string name, Func <T, string> formatter, T defaultValue)
        {
            string str       = null;
            var    parameter = properties.GetParameter <T>(name);

            if (parameter != null)
            {
                str = formatter(parameter);
            }
            else if (!properties.Items.TryGetValue(name, out str))
            {
                str = formatter(defaultValue);
            }
            properties.Items.Remove(name);
            if (str != null)
            {
                queryStrings[name] = str;
            }
        }
        protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
        {
            var queryStrings = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            queryStrings.Add("response_type", "code");
            queryStrings.Add("client_id", Options.ClientId);
            queryStrings.Add("redirect_uri", redirectUri);

            if (Options.AccessAllAccounts)
            {
                queryStrings.Add("account", "all");
            }

            if (null != Options.SendLimitAmount)
            {
                queryStrings.Add("meta[send_limit_amount]", Options.SendLimitAmount.ToString());
            }

            if (null != Options.SendLimitCurrency)
            {
                queryStrings.Add("meta[send_limit_currency]", Options.SendLimitCurrency.ToString());
            }

            if (null != Options.SendLimitPeriod)
            {
                queryStrings.Add("meta[send_limit_period]", Options.SendLimitPeriod.ToString());
            }

            var state = Options.StateDataFormat.Protect(properties);

            queryStrings.Add("state", state);

            var scopeParameter = properties.GetParameter <ICollection <string> >(OAuthChallengeProperties.ScopeKey);
            var scope          = scopeParameter != null?FormatScope(scopeParameter) : FormatScope();

            queryStrings.Add("scope", scope);

            var authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings);

            return(authorizationEndpoint);
        }
        protected override string BuildChallengeUrl(AuthenticationProperties properties, [NotNull] string redirectUri)
        {
            string value = base.Options.StateDataFormat.Protect(properties);
            Dictionary <string, string> dictionary = new Dictionary <string, string>
            {
                ["appid"]         = base.Options.AppID,
                ["scope"]         = FormatScope(),
                ["response_type"] = "code",
                ["redirect_uri"]  = redirectUri,
                ["state"]         = value
            };
            string parameter = properties.GetParameter <string>("loginTmpCode");

            if (!string.IsNullOrWhiteSpace(parameter))
            {
                dictionary.Add("loginTmpCode", parameter);
            }

            redirectUri = QueryHelpers.AddQueryString(base.Options.AuthorizationEndpoint, dictionary);
            return(redirectUri);
        }
예제 #16
0
        => string.Join(",", scopes);     // // OAuth2 3.3 space separated, but weixin not

        #region Pick value from AuthenticationProperties
        private static string PickAuthenticationProperty <T>(
            AuthenticationProperties properties,
            string name,
            Func <T, string> formatter,
            T defaultValue)
        {
            string value          = null;
            var    parameterValue = properties.GetParameter <T>(name);

            if (parameterValue != null)
            {
                value = formatter(parameterValue);
            }
            else if (!properties.Items.TryGetValue(name, out value))
            {
                value = formatter(defaultValue);
            }

            // Remove the parameter from AuthenticationProperties so it won't be serialized into the state
            properties.Items.Remove(name);

            return(value);
        }
        protected override string BuildChallengeUrl([NotNull] AuthenticationProperties properties, [NotNull] string redirectUri)
        {
            var scopeParameter = properties.GetParameter <ICollection <string> >(OAuthChallengeProperties.ScopeKey);
            var scope          = scopeParameter != null?FormatScope(scopeParameter) : FormatScope();

            var parameters = new Dictionary <string, string?>
            {
                ["client_id"]     = Options.ClientId,
                ["scope"]         = scope,
                ["response_type"] = "code"
            };

            if (Options.UsePkce)
            {
                var bytes = new byte[32];
                RandomNumberGenerator.Fill(bytes);
                var codeVerifier = Base64UrlTextEncoder.Encode(bytes);

                // Store this for use during the code redemption.
                properties.Items.Add(OAuthConstants.CodeVerifierKey, codeVerifier);

                var challengeBytes = SHA256.HashData(Encoding.UTF8.GetBytes(codeVerifier));
                var codeChallenge  = WebEncoders.Base64UrlEncode(challengeBytes);

                parameters[OAuthConstants.CodeChallengeKey]       = codeChallenge;
                parameters[OAuthConstants.CodeChallengeMethodKey] = OAuthConstants.CodeChallengeMethodS256;
            }

            var state = Options.StateDataFormat.Protect(properties);

            parameters["state"] = state;

            // Mixcloud does not appear to support the `state` parameter, so have to bundle it here:
            parameters["redirect_uri"] = QueryHelpers.AddQueryString(redirectUri, "state", state);

            return(QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, parameters));
        }
예제 #18
0
        private string PickAuthenticationProperty <T>(
            AuthenticationProperties properties,
            string name,
            Func <T, string> formatter,
            T defaultValue)
        {
            string value          = null;
            var    parameterValue = properties.GetParameter <T>(name);

            if (parameterValue != null)
            {
                value = formatter(parameterValue);
            }
            else if (!properties.Items.TryGetValue(name, out value))
            {
                value = formatter(defaultValue);
            }

            // Remove the parameter from AuthenticationProperties so it won't be serialized into the state
            Logger.LogWarning($"BuildChallengeUrl: properties.Items[\"{name}\"] with value \"{value}\" will be Picked!");
            properties.Items.Remove(name);

            return(value);
        }
예제 #19
0
        public static void AddQueryString <T>(this IDictionary <string, string> querystring, T defaultValue,
                                              AuthenticationProperties properties, string keyName, Func <T, string> stringFormatter = null)
        {
            var value        = string.Empty;
            T   getParameter = default;

            //Difference between this and going to the actual collection items through
            //properties.Items
            var parameterValue = properties.GetParameter <T>(keyName);

            if (parameterValue != null)
            {
                getParameter = parameterValue;
            }

            value = stringFormatter != null?
                    stringFormatter(getParameter) :
                        getParameter?.ToString();

            if (!string.IsNullOrWhiteSpace(value))
            {
                querystring[keyName] = value;
            }
        }