Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="session">Ramone session.</param>
        /// <param name="scope">Space separated list of strings identifying the required scopes (as defined by the authorization server).</param>
        /// <param name="extraRequestArgs">Optionally specify extra arguments in the POST data of the HTTP request.</param>
        /// <param name="useAccessToken">Store the returned access token in session and use that in future requests to the resource server.</param>
        /// <returns></returns>
        public static OAuth2AccessTokenResponse OAuth2_GetAccessTokenUsingClientCredentials(
            this ISession session,
            string scope = null,
            IDictionary <string, string> extraRequestArgs = null,
            bool useAccessToken = true)
        {
            OAuth2Settings settings = GetSettings(session);

            NameValueCollection tokenRequestArgs = new NameValueCollection();

            tokenRequestArgs["grant_type"] = "client_credentials";
            if (scope != null)
            {
                tokenRequestArgs["scope"] = scope;
            }

            if (extraRequestArgs != null)
            {
                foreach (var kv in extraRequestArgs)
                {
                    tokenRequestArgs[kv.Key] = kv.Value;
                }
            }

            if (settings.ClientAuthenticationMethod == OAuth2Settings.DefaultClientAuthenticationMethods.RequestBody)
            {
                tokenRequestArgs["client_id"]     = settings.ClientID;
                tokenRequestArgs["client_secret"] = settings.ClientSecret;
            }

            return(GetAndStoreAccessToken(session, tokenRequestArgs, useAccessToken));
        }
Esempio n. 2
0
        /// <summary>
        /// Request access token, passing the supplied args to the OAuth2 endpoint.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="args"></param>
        /// <param name="useAccessToken">Store the returned access token in session and use that in future requests to the resource server.</param>
        /// <returns></returns>
        public static OAuth2AccessTokenResponse GetAndStoreAccessToken(ISession session, object args, bool useAccessToken)
        {
            OAuth2Settings settings = GetSettings(session);

            Request request = session.Bind(settings.TokenEndpoint)
                              .AsFormUrlEncoded()
                              .AcceptJson();

            if (settings.ClientAuthenticationMethod == OAuth2Settings.DefaultClientAuthenticationMethods.BasicAuthenticationHeader)
            {
                request = request.BasicAuthentication(settings.ClientID, settings.ClientSecret);
            }

            using (var response = request.AcceptJson().Post <Hashtable>(args))
            {
                OAuth2AccessTokenResponse accessToken = new OAuth2AccessTokenResponse
                {
                    access_token  = TryGet <string>(response.Body["access_token"]),
                    token_type    = TryGet <string>(response.Body["token_type"]),
                    expires_in    = TryGet <long?>(response.Body["expires_in"]),
                    refresh_token = TryGet <string>(response.Body["refresh_token"]),
                    AllParameters = response.Body
                };

                if (useAccessToken)
                {
                    OAuth2SessionState state = session.OAuth2_GetOrCreateState();
                    state.AccessToken = accessToken.access_token;
                    state.TokenType   = ParseAccessTokenType(accessToken.token_type);

                    OAuth2_ActivateAuthorization(session, accessToken.access_token, state.TokenType);
                }
                return(accessToken);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Request an access token from authorization code acquired in earlier requests.
        /// </summary>
        /// <remarks>See http://tools.ietf.org/html/rfc6749#section-4.1.3</remarks>
        /// <param name="session">Ramone session.</param>
        /// <param name="authorizationCode"></param>
        /// <param name="extraRequestArgs">Optionally specify extra arguments in the POST data of the HTTP request.</param>
        /// <param name="useAccessToken">Request automatic use of the returned access token in following requests.</param>
        /// <returns></returns>
        public static OAuth2AccessTokenResponse OAuth2_GetAccessTokenFromAuthorizationCode(
            this ISession session,
            string authorizationCode,
            IDictionary <string, string> extraRequestArgs = null,
            bool useAccessToken = true)
        {
            OAuth2Settings settings = GetSettings(session);

            NameValueCollection tokenRequestArgs = new NameValueCollection();

            tokenRequestArgs["grant_type"]   = "authorization_code";
            tokenRequestArgs["code"]         = authorizationCode;
            tokenRequestArgs["redirect_uri"] = settings.RedirectUri.ToString();

            if (extraRequestArgs != null)
            {
                foreach (var kv in extraRequestArgs)
                {
                    tokenRequestArgs[kv.Key] = kv.Value;
                }
            }

            if (settings.ClientAuthenticationMethod == OAuth2Settings.DefaultClientAuthenticationMethods.RequestBody)
            {
                tokenRequestArgs["client_id"]     = settings.ClientID;
                tokenRequestArgs["client_secret"] = settings.ClientSecret;
            }

            return(GetAndStoreAccessToken(session, tokenRequestArgs, useAccessToken));
        }
Esempio n. 4
0
        /// <summary>
        /// Get an access token using the flow "Client Credentials Grant" with JWT client credentials signed with a generic algorithm.
        /// </summary>
        /// <param name="session">Ramone session.</param>
        /// <param name="signingAlgorithm">An implementation of ISigningAlgorithm to do the actual signing.</param>
        /// <param name="args">Assertion arguments.</param>
        /// <param name="useAccessToken">Store the returned access token in session and use that in future requests to the resource server.</param>
        /// <returns></returns>
        public static OAuth2AccessTokenResponse OAuth2_GetAccessTokenFromJWT(this ISession session, Jose.JwsAlgorithm alg, object key, AssertionArgs args, bool useAccessToken = true)
        {
            OAuth2Settings settings = GetSettings(session);

            DateTime now          = DateTime.UtcNow;
            DateTime issuedAtDate = now.Add(args.IssueTimeOffset);
            DateTime expiresDate  = issuedAtDate.Add(args.ExpireTime);
            long     issuedAt     = issuedAtDate.ToUnixTime();
            long     expires      = expiresDate.ToUnixTime();

            var claims = new Dictionary <string, object>()
            {
                { "iss", args.Issuer },
                { "scope", args.Scope },
                { "aud", args.Audience },
                { "sub", args.Subject },
                { "exp", expires },
                { "iat", issuedAt }
            };

            claims = claims.Where(kv => kv.Value != null).ToDictionary(kv => kv.Key, kv => kv.Value);

            string token = Jose.JWT.Encode(claims, key, alg);

            NameValueCollection tokenRequestArgs = new NameValueCollection();

            tokenRequestArgs["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
            tokenRequestArgs["assertion"]  = token;

            return(GetAndStoreAccessToken(session, tokenRequestArgs, useAccessToken));
        }
Esempio n. 5
0
        /// <summary>
        /// Request an access token using the flow "Resource Owner Password Credentials Grant".
        /// </summary>
        /// <remarks>See http://tools.ietf.org/html/rfc6749#section-4.3</remarks>
        /// <param name="session">Ramone session.</param>
        /// <param name="ownerUserName"></param>
        /// <param name="ownerPassword"></param>
        /// <param name="scope">Space separated list of strings identifying the required scopes (as defined by the authorization server).</param>
        /// <param name="useAccessToken">Request automatic use of the returned access token in following requests.</param>
        /// <returns></returns>
        public static OAuth2AccessTokenResponse OAuth2_GetAccessTokenUsingOwnerUsernamePassword(
            this ISession session,
            string ownerUserName,
            string ownerPassword,
            string scope        = null,
            bool useAccessToken = true)
        {
            OAuth2Settings settings = GetSettings(session);

            NameValueCollection tokenRequestArgs = new NameValueCollection();

            tokenRequestArgs["grant_type"] = "password";
            tokenRequestArgs["username"]   = ownerUserName;
            if (ownerPassword != null)
            {
                tokenRequestArgs["password"] = ownerPassword;
            }
            if (scope != null)
            {
                tokenRequestArgs["scope"] = scope;
            }

            if (settings.ClientAuthenticationMethod == OAuth2Settings.DefaultClientAuthenticationMethods.RequestBody)
            {
                tokenRequestArgs["client_id"]     = settings.ClientID;
                tokenRequestArgs["client_secret"] = settings.ClientSecret;
            }

            return(GetAndStoreAccessToken(session, tokenRequestArgs, useAccessToken));
        }
Esempio n. 6
0
        /// <summary>
        /// Configure OAuth2 and store configuration in session for later use.
        /// Must always be called before using any of the other OAuth2 methods.
        /// </summary>
        /// <param name="session">Ramone session.</param>
        /// <param name="settings"></param>
        /// <returns>The session passed in as argument.</returns>
        public static ISession OAuth2_Configure(this ISession session, OAuth2Settings settings)
        {
            Condition.Requires(settings, "settings").IsNotNull();

            session.Items[OAuth2SettingsSessionKey] = settings;

            return(session);
        }
Esempio n. 7
0
        public static OAuth2AccessTokenResponse OAuth2_RefreshAccessToken(this ISession session, string refreshToken, string scope = null, bool useAccessToken = true)
        {
            OAuth2Settings settings = GetSettings(session);

            NameValueCollection tokenRequestArgs = new NameValueCollection();

            tokenRequestArgs["grant_type"]    = "refresh_token";
            tokenRequestArgs["refresh_token"] = refreshToken;
            tokenRequestArgs["scope"]         = scope;

            if (settings.ClientAuthenticationMethod == OAuth2Settings.DefaultClientAuthenticationMethods.RequestBody)
            {
                tokenRequestArgs["client_id"]     = settings.ClientID;
                tokenRequestArgs["client_secret"] = settings.ClientSecret;
            }

            return(GetAndStoreAccessToken(session, tokenRequestArgs, useAccessToken));
        }
Esempio n. 8
0
        /// <summary>
        /// Get URL for user authorization via browser (user agent). This will initiate the "Authorization Code Grant" flow.
        /// </summary>
        /// <remarks>See http://tools.ietf.org/html/rfc6749#section-4.1.1</remarks>
        /// <param name="session">Ramone session.</param>
        /// <param name="scope">Space separated list of strings identifying the required scopes (as defined by the authorization server).</param>
        /// <returns>Authorization request URL.</returns>
        public static Uri OAuth2_GetAuthorizationRequestUrl(this ISession session, string scope = null)
        {
            OAuth2Settings settings = GetSettings(session);

            string             authorizationRequestState = RandomStrings.GetRandomStringWithLettersAndDigitsOnly(20);
            OAuth2SessionState state = session.OAuth2_GetOrCreateState();

            state.AuthorizationState = authorizationRequestState;

            var codeRequestArgs = new
            {
                response_type = "code",
                client_id     = settings.ClientID,
                redirect_uri  = settings.RedirectUri.ToString(),
                scope         = scope,
                state         = authorizationRequestState
            };

            return(settings.AuthorizationEndpoint.AddQueryParameters(codeRequestArgs));
        }
Esempio n. 9
0
        /// <summary>
        /// Get an access token using either the flow "JWTs as Authorization Grants" defined in RFC 7523 Section 2.1 or
        /// "Client Acting on Behalf of Itself" defined in RFC 7521 Section 6.2 with JWT client credentials signed with a generic algorithm.
        /// </summary>
        /// <param name="session">Ramone session.</param>
        /// <param name="alg">An implementation of ISigningAlgorithm to do the actual signing.<</param>
        /// <param name="key">The key used by the signing algorithm.</param>
        /// <param name="args">Assertion arguments.</param>
        /// <param name="flowType">Specify which client authentication flow to use.</param>
        /// <param name="extraHeaders">Optionally specify extra headers in the assertion.</param>
        /// <param name="extraClaims">Optionally specify extra claims in the assertion.</param>
        /// <param name="extraRequestArgs">Optionally specify extra arguments in the POST data of the HTTP request.</param>
        /// <param name="useAccessToken">Store the returned access token in session and use that in future requests to the resource server.</param>
        /// <returns></returns>
        public static OAuth2AccessTokenResponse OAuth2_GetAccessTokenFromJWT(
            this ISession session,
            Jose.JwsAlgorithm alg,
            object key,
            AssertionArgs args,
            ClientAuthenticationFlowType flowType,
            IDictionary <string, object> extraHeaders     = null,
            IDictionary <string, object> extraClaims      = null,
            IDictionary <string, string> extraRequestArgs = null,
            bool useAccessToken = true)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            if (flowType != ClientAuthenticationFlowType.Rfc7523Section21 && flowType != ClientAuthenticationFlowType.Rfc7521Section62)
            {
                throw new ArgumentOutOfRangeException(nameof(flowType));
            }

            OAuth2Settings settings = GetSettings(session);

            DateTime now          = DateTime.UtcNow;
            DateTime issuedAtDate = now.Add(args.IssueTimeOffset);
            DateTime expiresDate  = issuedAtDate.Add(args.ExpireTime);
            long     issuedAt     = issuedAtDate.ToUnixTime();
            long     expires      = expiresDate.ToUnixTime();

            IEnumerable <KeyValuePair <string, object> > baseClaims = new Dictionary <string, object>()
            {
                { "iss", args.Issuer },
                { "scope", args.Scope },
                { "aud", args.Audience },
                { "sub", args.Subject },
                { "exp", expires },
                { "iat", issuedAt }
            };

            if (extraClaims != null)
            {
                baseClaims = baseClaims.Concat(extraClaims);
            }
            var claims = baseClaims.Where(kv => kv.Value != null).ToDictionary(kv => kv.Key, kv => kv.Value);

            string token = Jose.JWT.Encode(claims, key, alg, extraHeaders: extraHeaders);

            NameValueCollection tokenRequestArgs = new NameValueCollection();

            if (flowType == ClientAuthenticationFlowType.Rfc7523Section21)
            {
                tokenRequestArgs["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
                tokenRequestArgs["assertion"]  = token;
            }
            else
            {
                tokenRequestArgs["scope"]                 = args.Scope; // This is nominally optional and redundant, but Microsoft wants it...
                tokenRequestArgs["grant_type"]            = "client_credentials";
                tokenRequestArgs["client_assertion_type"] = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
                tokenRequestArgs["client_assertion"]      = token;
            }
            if (extraRequestArgs != null)
            {
                foreach (var kv in extraRequestArgs)
                {
                    tokenRequestArgs[kv.Key] = kv.Value;
                }
            }

            return(GetAndStoreAccessToken(session, tokenRequestArgs, useAccessToken));
        }
Esempio n. 10
0
        static void Setup()
        {
            // Create new session with implicit service
              Session = RamoneConfiguration.NewSession(new Uri(GoogleAPIBaseUrl));

              // Get Google API keys from file (don't want the secret parts hardcoded in public repository)
              GoogleKeys keys = new GoogleKeys();
              if (SelectedAccessType != AccessType.JWT)
            keys = ReadKeys();

              // Configure OAuth2 with the stuff it needs for it's magic
              OAuth2Settings settings = new OAuth2Settings
              {
            TokenEndpoint = new Uri(TokenEndpointUrl)
              };

              if (SelectedAccessType == AccessType.PinCode)
              {
            settings.AuthorizationEndpoint = new Uri(AuthorizationEndpointUrl);
            settings.RedirectUri = new Uri("urn:ietf:wg:oauth:2.0:oob");
            settings.ClientID = keys.ClientId;
            settings.ClientSecret = keys.ClientSecret;
            settings.ClientAuthenticationMethod = OAuth2Settings.DefaultClientAuthenticationMethods.RequestBody;
              }
              else if (SelectedAccessType == AccessType.Redirect)
              {
            settings.AuthorizationEndpoint = new Uri(AuthorizationEndpointUrl);
            settings.RedirectUri = new Uri("http://localhost");
            settings.ClientID = keys.ClientId;
            settings.ClientSecret = keys.ClientSecret;
            settings.ClientAuthenticationMethod = OAuth2Settings.DefaultClientAuthenticationMethods.RequestBody;
              }
              else
              {
            settings.ClientAuthenticationMethod = OAuth2Settings.DefaultClientAuthenticationMethods.Other;
              }

              Session.OAuth2_Configure(settings);
        }