コード例 #1
0
        public OIDCClientInformation RegisterClient(string RegistrationEndpoint, OIDCClientInformation clientMetadata, string TokenEndpointAuthMethod = "client_secret_basic")
        {
            // Make registration request
            OIDCClientRegistrationRequest registrationRequest = new OIDCClientRegistrationRequest();

            registrationRequest.ApplicationType         = clientMetadata.ApplicationType;
            registrationRequest.RedirectUris            = clientMetadata.RedirectUris;
            registrationRequest.ResponseTypes           = clientMetadata.ResponseTypes;
            registrationRequest.TokenEndpointAuthMethod = TokenEndpointAuthMethod;

            // Check error and store client information from OP
            WebRequest request = WebRequest.Create(RegistrationEndpoint);
            Dictionary <string, object> returnedJson = PostUrlContent(request, registrationRequest, true);

            if (returnedJson.Keys.Contains("error"))
            {
                OIDCResponseError error = new OIDCResponseError();
                throw new OIDCException("Error while registering client: " + error.Error + "\n" + error.ErrorDescription);
            }

            OIDCClientInformation clientInformation = new OIDCClientInformation();

            clientInformation.deserializeFromDynamic(returnedJson);
            return(clientInformation);
        }
コード例 #2
0
        public void Should_Accept_Encrypted_UserInfo()
        {
            rpid = "rp-user_info-enc";

            // given
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";
            clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.IdToken };
            clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "id_token_flow_callback" };
            clientMetadata.UserinfoEncryptedResponseAlg = "RSA1_5";
            clientMetadata.UserinfoEncryptedResponseEnc = "A128CBC-HS256";
            clientMetadata.JwksUri = myBaseUrl + "my_public_keys.jwks";
            OIDCClientInformation clientInformation = rp.RegisterClient(registrationEndopoint, clientMetadata);

            OIDClaims requestClaims = new OIDClaims();
            requestClaims.IdToken = new Dictionary<string, OIDClaimData>();
            requestClaims.IdToken.Add("name", new OIDClaimData());

            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = clientInformation.ClientId;
            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid, MessageScope.Profile, MessageScope.Address, MessageScope.Phone, MessageScope.Email };
            requestMessage.ResponseType = new List<ResponseType>() { ResponseType.IdToken, ResponseType.Token };
            requestMessage.RedirectUri = clientInformation.RedirectUris[0];
            requestMessage.Nonce = WebOperations.RandomString();
            requestMessage.State = WebOperations.RandomString();
            requestMessage.Claims = requestClaims;
            requestMessage.Validate();

            rp.Authenticate(GetBaseUrl("/authorization"), requestMessage);
            semaphore.WaitOne();
            OIDCAuthImplicitResponseMessage authResponse = rp.ParseAuthImplicitResponse(result, requestMessage.Scope, requestMessage.State);

            X509Certificate2 encCert = new X509Certificate2("server.pfx", "", X509KeyStorageFlags.Exportable);
            List<OIDCKey> myKeys = KeyManager.GetKeysJwkList(null, encCert);

            // when
            OIDCUserInfoResponseMessage response = GetUserInfo(authResponse.Scope, authResponse.State, authResponse.AccessToken, null, true, null, myKeys);

            // then
            response.Validate();
            Assert.IsNotNullOrEmpty(response.Name);
        }
        public void Should_Client_Be_Able_To_Register()
        {
            rpid = "rp-registration-dynamic";

            // given
            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";
            clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "code_flow_callback" };
            clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.Code };
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            OIDCClientInformation response = rp.RegisterClient(registrationEndopoint, clientMetadata);

            // then
            response.Validate();
        }
        public void Should_Client_Only_Use_Https_Endpoints()
        {
            rpid = "rp-registration-uses_https_endpoints";

            // given
            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";
            clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "code_flow_callback" };
            clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.Code };
            clientMetadata.JwksUri = myBaseUrl + "my_public_keys.jwks";
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            OIDCClientInformation response = rp.RegisterClient(registrationEndopoint, clientMetadata);
            response.JwksUri = clientMetadata.JwksUri.Replace("https", "http");

            // then
            response.Validate();
        }
コード例 #5
0
        /// <summary>
        /// Method that validates the IdToken with specific rules
        /// </summary>
        /// <param name="idToken"></param>
        /// <param name="clientInformation"></param>
        /// <param name="providerMetadata"></param>
        /// <param name="nonce"></param>
        public void ValidateIdToken(OIDCIdToken idToken, OIDCClientInformation clientInformation, string Issuer, string Nonce)
        {
            if (idToken.Iss.Trim('/') != Issuer.Trim('/'))
            {
                throw new OIDCException("Wrong issuer for the token.");
            }

            if (Issuer != "https://self-issued.me" && !idToken.Aud.Contains(clientInformation.ClientId))
            {
                throw new OIDCException("Intended audience of the token does not include client_id.");
            }

            if (idToken.Aud.Count > 1 && idToken.Azp == null)
            {
                throw new OIDCException("Multiple audience but no authorized party specified.");
            }

            if (idToken.Azp != null && idToken.Azp != clientInformation.ClientId)
            {
                throw new OIDCException("The authorized party does not match client_id.");
            }

            if (idToken.Exp < DateTime.UtcNow - new TimeSpan(0, 10, 0))
            {
                throw new OIDCException("The token is expired.");
            }

            if (idToken.Iat < DateTime.Now - new TimeSpan(24, 0, 0))
            {
                throw new OIDCException("The token has ben issued more than a day ago.");
            }

            if (Nonce != null && idToken.Nonce != Nonce)
            {
                throw new OIDCException("Wrong nonce value in token.");
            }
        }
コード例 #6
0
        /// <summary>
        /// Method that performs a dynamic client registration with the OP server.
        /// </summary>
        /// <param name="RegistrationEndpoint">The URL of the OP describing the registration endpoint.</param>
        /// <param name="clientMetadata">The OIDCClientInformation object describing the client information to
        /// be submitted to the OP for registration.</param>
        /// <param name="TokenEndpointAuthMethod">(optional) the endpoint authentication method used to
        /// authenticate the client with the OP sever (if not specified using "client_secret_basic".</param>
        /// <returns>An oject describing all client information as returned by the OP server after
        /// registration.</returns>
        /// <exception cref="OpenIDClient.OIDCException">Thrown when an error occurs while registering
        /// the client with the OP.</exception>
        public OIDCClientInformation RegisterClient(string RegistrationEndpoint, OIDCClientInformation clientMetadata, string TokenEndpointAuthMethod = "client_secret_basic")
        {
            // Make registration request
            Dictionary <string, object>   data = clientMetadata.SerializeToDictionary();
            OIDCClientRegistrationRequest registrationRequest = new OIDCClientRegistrationRequest();

            registrationRequest.DeserializeFromDictionary(data);

            // Check error and store client information from OP
            WebRequest request        = WebRequest.Create(RegistrationEndpoint);
            string     returnedString = WebOperations.PostUrlContent(request, registrationRequest, true);
            Dictionary <string, object> returnedJson = Deserializer.DeserializeFromJson <Dictionary <string, object> >(returnedString);

            if (returnedJson.Keys.Contains("error"))
            {
                OIDCResponseError error = new OIDCResponseError();
                throw new OIDCException("Error while registering client: " + error.Error + "\n" + error.ErrorDescription);
            }

            OIDCClientInformation clientInformation = new OIDCClientInformation();

            clientInformation.DeserializeFromDictionary(returnedJson);
            return(clientInformation);
        }
コード例 #7
0
        private OIDCClientSecretJWT AddClientAuthenticatedToRequest(ref WebRequest request, ref OIDCAuthenticatedMessage requestMessage, string grantType, OIDCClientInformation clientInformation, byte[] privateKey)
        {
            OIDCClientSecretJWT tokenData = null;
            byte[] encKey = null;
            switch (grantType)
            {
                case "client_secret_basic":
                    string basic = clientInformation.ClientId + ":" + clientInformation.ClientSecret;
                    basic = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(basic));
                    request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(basic)));
                    break;
                case "client_secret_post":
                    requestMessage.ClientId = clientInformation.ClientId;
                    requestMessage.ClientSecret = clientInformation.ClientSecret;
                    break;
                case "client_secret_jwt":
                    encKey = Encoding.UTF8.GetBytes(clientInformation.ClientSecret);
                    break;
                case "private_key_jwt":
                    encKey = privateKey;
                    break;
                default: // case "none"
                    break;
            }

            // If client_secret_jwt or private_key_jwt pass a JWT bearer token with the
            // specified key for encryption.
            if (encKey != null)
            {
                tokenData = new OIDCClientSecretJWT();
                tokenData.Iss = clientInformation.ClientId;
                tokenData.Sub = clientInformation.ClientId;
                tokenData.Aud = request.RequestUri.ToString();
                if (tokenData.Aud.Contains("?"))
                {
                    tokenData.Aud = tokenData.Aud.Substring(0, tokenData.Aud.IndexOf("?"));
                }
                tokenData.Jti = WebOperations.RandomString();
                tokenData.Exp = DateTime.Now;
                tokenData.Iat = DateTime.Now - new TimeSpan(0, 10, 0);
                requestMessage.ClientAssertionType = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
                requestMessage.ClientAssertion = JWT.Encode(tokenData, encKey, Jose.JwsAlgorithm.HS256);
            }

            return tokenData;
        }
コード例 #8
0
        /// <summary>
        /// Method that submits a tokn request to the OP.
        /// </summary>
        /// <param name="url">The URL to be used where to send the request</param>
        /// <param name="tokenRequestMessage">The token request message</param>
        /// <param name="clientInformation">The client information obtained from the OP</param>
        /// <returns>Returns the token response obtained from the OP</returns>
        public OIDCTokenResponseMessage SubmitTokenRequest(string url, OIDCTokenRequestMessage tokenRequestMessage, OIDCClientInformation clientInformation, byte[] privateKey = null)
        {
            WebRequest request = WebRequest.Create(url);
            OIDCAuthenticatedMessage message = tokenRequestMessage as OIDCAuthenticatedMessage;
            string grantType = clientInformation.TokenEndpointAuthMethod;

            AddClientAuthenticatedToRequest(ref request, ref message, grantType, clientInformation, privateKey);
            string returnedString = WebOperations.PostUrlContent(request, message);
            Dictionary <string, object> returnedJson = Deserializer.DeserializeFromJson <Dictionary <string, object> >(returnedString);

            if (returnedJson.Keys.Contains("error"))
            {
                OIDCResponseError error = new OIDCResponseError();
                error.DeserializeFromDictionary(returnedJson);
                throw new OIDCException("Error while registering client: " + error.Error + "\n" + error.ErrorDescription);
            }

            OIDCTokenResponseMessage tokenResponse = new OIDCTokenResponseMessage();

            tokenResponse.DeserializeFromDictionary(returnedJson);
            return(tokenResponse);
        }
コード例 #9
0
        private OIDCClientSecretJWT AddClientAuthenticatedToRequest(ref WebRequest request, ref OIDCAuthenticatedMessage requestMessage, string grantType, OIDCClientInformation clientInformation, byte[] privateKey)
        {
            OIDCClientSecretJWT tokenData = null;

            byte[] encKey = null;
            switch (grantType)
            {
            case "client_secret_basic":
                string basic = clientInformation.ClientId + ":" + clientInformation.ClientSecret;
                basic = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(basic));
                request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(basic)));
                break;

            case "client_secret_post":
                requestMessage.ClientId     = clientInformation.ClientId;
                requestMessage.ClientSecret = clientInformation.ClientSecret;
                break;

            case "client_secret_jwt":
                encKey = Encoding.UTF8.GetBytes(clientInformation.ClientSecret);
                break;

            case "private_key_jwt":
                encKey = privateKey;
                break;

            default:     // case "none"
                break;
            }

            // If client_secret_jwt or private_key_jwt pass a JWT bearer token with the
            // specified key for encryption.
            if (encKey != null)
            {
                tokenData     = new OIDCClientSecretJWT();
                tokenData.Iss = clientInformation.ClientId;
                tokenData.Sub = clientInformation.ClientId;
                tokenData.Aud = request.RequestUri.ToString();
                if (tokenData.Aud.Contains("?"))
                {
                    tokenData.Aud = tokenData.Aud.Substring(0, tokenData.Aud.IndexOf("?"));
                }
                tokenData.Jti = WebOperations.RandomString();
                tokenData.Exp = DateTime.Now;
                tokenData.Iat = DateTime.Now - new TimeSpan(0, 10, 0);
                requestMessage.ClientAssertionType = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
                requestMessage.ClientAssertion     = JWT.Encode(tokenData, encKey, Jose.JwsAlgorithm.HS256);
            }

            return(tokenData);
        }
コード例 #10
0
        public OIDCTokenResponseMessage SubmitTokenRequest(string url, OIDCTokenRequestMessage tokenRequestMessage, OIDCClientInformation clientInformation)
        {
            WebRequest request = WebRequest.Create(url);
            OIDCAuthenticatedMessage message = tokenRequestMessage as OIDCAuthenticatedMessage;
            string grantType = clientInformation.TokenEndpointAuthMethod;
            OIDCClientSecretJWT         tokenData    = AddClientAuthenticatedToRequest(ref request, ref message, grantType, clientInformation);
            Dictionary <string, object> returnedJson = PostUrlContent(request, message);

            if (returnedJson.Keys.Contains("error"))
            {
                OIDCResponseError error = new OIDCResponseError();
                error.deserializeFromDynamic(returnedJson);
                throw new OIDCException("Error while registering client: " + error.Error + "\n" + error.ErrorDescription);
            }

            OIDCTokenResponseMessage tokenResponse = new OIDCTokenResponseMessage();

            tokenResponse.deserializeFromDynamic(returnedJson);
            return(tokenResponse);
        }
        public void Should_Keys_Be_Published_As_JWK()
        {
            rpid = "rp-registration-well_formed_jwk";

            // given
            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";
            clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "code_flow_callback" };
            clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.Code };
            clientMetadata.JwksUri = myBaseUrl + "my_public_keys.jwks";
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            OIDCClientInformation response = rp.RegisterClient(registrationEndopoint, clientMetadata);

            // then
            response.Validate();
        }
        public void Should_Registration_Request_Has_RedirectUris()
        {
            rpid = "rp-registration-redirect_uris";

            // given
            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";
            clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "code_flow_callback" };
            clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.Code };
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            OIDCClientInformation response = rp.RegisterClient(registrationEndopoint, clientMetadata);

            // then
            response.Validate();
            CollectionAssert.AreEquivalent(clientMetadata.RedirectUris, response.RedirectUris);
        }
コード例 #13
0
        public void Should_Accept_Signed_UserInfo()
        {
            rpid = "rp-user_info-sign";

            // given
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";
            clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.IdToken };
            clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "id_token_flow_callback" };
            clientMetadata.UserinfoSignedResponseAlg = "HS256";
            clientMetadata.JwksUri = myBaseUrl + "my_public_keys.jwks";
            OIDCClientInformation clientInformation = rp.RegisterClient(registrationEndopoint, clientMetadata);

            OIDClaims requestClaims = new OIDClaims();
            requestClaims.IdToken = new Dictionary<string, OIDClaimData>();
            requestClaims.IdToken.Add("name", new OIDClaimData());

            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = clientInformation.ClientId;
            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid, MessageScope.Profile, MessageScope.Address, MessageScope.Phone, MessageScope.Email };
            requestMessage.ResponseType = new List<ResponseType>() { ResponseType.IdToken, ResponseType.Token };
            requestMessage.RedirectUri = clientInformation.RedirectUris[0];
            requestMessage.Nonce = WebOperations.RandomString();
            requestMessage.State = WebOperations.RandomString();
            requestMessage.Claims = requestClaims;
            requestMessage.Validate();

            rp.Authenticate(GetBaseUrl("/authorization"), requestMessage);
            semaphore.WaitOne();
            OIDCAuthImplicitResponseMessage authResponse = rp.ParseAuthImplicitResponse(result, requestMessage.Scope, requestMessage.State);

            // when
            OIDCUserInfoResponseMessage response = GetUserInfo(authResponse.Scope, authResponse.State, authResponse.AccessToken, null, true, clientInformation.ClientSecret, null);

            // then
            response.Validate();
            Assert.IsNotNullOrEmpty(response.Name);
        }
コード例 #14
0
        private OIDCClientSecretJWT AddClientAuthenticatedToRequest(ref WebRequest request, ref OIDCAuthenticatedMessage requestMessage, string grantType, OIDCClientInformation clientInformation)
        {
            OIDCClientSecretJWT tokenData = null;

            switch (grantType)
            {
            case "client_secret_basic":
                string basic = clientInformation.ClientId + ":" + clientInformation.ClientSecret;
                request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(basic)));
                break;

            case "client_secret_post":
                requestMessage.ClientId     = clientInformation.ClientId;
                requestMessage.ClientSecret = clientInformation.ClientSecret;
                break;

            case "client_secret_jwt":
            case "private_key_jwt":
                // TODO understand how to sign JWT
                tokenData     = new OIDCClientSecretJWT();
                tokenData.Iss = clientInformation.ClientId;
                tokenData.Sub = clientInformation.ClientId;
                tokenData.Aud = request.RequestUri.ToString();
                if (tokenData.Aud.Contains("?"))
                {
                    tokenData.Aud = tokenData.Aud.Substring(0, tokenData.Aud.IndexOf("?"));
                }
                tokenData.Jti = RandomString();
                tokenData.Exp = DateTime.Now;
                tokenData.Iat = DateTime.Now - new TimeSpan(0, 10, 0);
                requestMessage.ClientAssertionType = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
                requestMessage.ClientAssertion     = JsonWebToken.Encode(tokenData, Encoding.UTF8.GetBytes(clientInformation.ClientSecret), JwtHashAlgorithm.HS256);
                break;

            default:     // case "none"
                break;
            }

            return(tokenData);
        }
コード例 #15
0
        public void RegisterClient(ResponseType? RespType, bool JWKs = false, bool RequestUri = false, bool InitateLoginUri = false)
        {
            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";

            if (JWKs)
            {
                clientMetadata.JwksUri = myBaseUrl + "my_public_keys.jwks";
            }

            if (RequestUri)
            {
                clientMetadata.RequestUris = new List<string>() { myBaseUrl + "request.jwt" };
            }

            if (InitateLoginUri)
            {
                clientMetadata.InitiateLoginUri = myBaseUrl + "initiated_login";
            }

            if (ResponseType.IdToken == RespType)
            {
                clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.IdToken };
                clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "id_token_flow_callback" };

            }
            else if(ResponseType.Code == RespType)
            {
                clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.Code };
                clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "code_flow_callback" };
            }
            else
            {
                clientMetadata.ResponseTypes = new List<ResponseType>() {
                    ResponseType.Code,
                    ResponseType.IdToken
                };
                clientMetadata.RedirectUris = new List<string>() {
                    myBaseUrl + "code_flow_callback",
                    myBaseUrl + "id_token_flow_callback"
                };
            }

            OpenIdRelyingParty rp = new OpenIdRelyingParty();
            clientInformation = rp.RegisterClient(registrationEndopoint, clientMetadata);
        }
コード例 #16
0
        /// <summary>
        /// Method that validates the IdToken with specific rules
        /// </summary>
        /// <param name="idToken"></param>
        /// <param name="clientInformation"></param>
        /// <param name="providerMetadata"></param>
        /// <param name="nonce"></param>
        public void ValidateIdToken(OIDCIdToken idToken, OIDCClientInformation clientInformation, string Issuer, string Nonce)
        {
            if (idToken.Iss.Trim('/') != Issuer.Trim('/'))
            {
                throw new OIDCException("Wrong issuer for the token.");
            }

            if (Issuer != "https://self-issued.me" && !idToken.Aud.Contains(clientInformation.ClientId))
            {
                throw new OIDCException("Intended audience of the token does not include client_id.");
            }

            if (idToken.Aud.Count > 1 && idToken.Azp == null)
            {
                throw new OIDCException("Multiple audience but no authorized party specified.");
            }

            if (idToken.Azp != null && idToken.Azp != clientInformation.ClientId)
            {
                throw new OIDCException("The authorized party does not match client_id.");
            }

            if (idToken.Exp < DateTime.UtcNow - new TimeSpan(0, 10, 0))
            {
                throw new OIDCException("The token is expired.");
            }

            if (idToken.Iat < DateTime.Now - new TimeSpan(24, 0, 0))
            {
                throw new OIDCException("The token has ben issued more than a day ago.");
            }

            if (Nonce != null && idToken.Nonce != Nonce)
            {
                throw new OIDCException("Wrong nonce value in token.");
            }
        }
コード例 #17
0
        /// <summary>
        /// Method that submits a tokn request to the OP.
        /// </summary>
        /// <param name="url">The URL to be used where to send the request</param>
        /// <param name="tokenRequestMessage">The token request message</param>
        /// <param name="clientInformation">The client information obtained from the OP</param>
        /// <returns>Returns the token response obtained from the OP</returns>
        public OIDCTokenResponseMessage SubmitTokenRequest(string url, OIDCTokenRequestMessage tokenRequestMessage, OIDCClientInformation clientInformation, byte[] privateKey = null)
        {
            WebRequest request = WebRequest.Create(url);
            OIDCAuthenticatedMessage message = tokenRequestMessage as OIDCAuthenticatedMessage;
            string grantType = clientInformation.TokenEndpointAuthMethod;
            AddClientAuthenticatedToRequest(ref request, ref message, grantType, clientInformation, privateKey);
            string returnedString = WebOperations.PostUrlContent(request, message);
            Dictionary<string, object> returnedJson = Deserializer.DeserializeFromJson<Dictionary<string, object>>(returnedString);

            if (returnedJson.Keys.Contains("error"))
            {
                OIDCResponseError error = new OIDCResponseError();
                error.DeserializeFromDictionary(returnedJson);
                throw new OIDCException("Error while registering client: " + error.Error + "\n" + error.ErrorDescription);
            }

            OIDCTokenResponseMessage tokenResponse = new OIDCTokenResponseMessage();
            tokenResponse.DeserializeFromDictionary(returnedJson);
            return tokenResponse;
        }
コード例 #18
0
        /// <summary>
        /// Method that performs a dynamic client registration with the OP server.
        /// </summary>
        /// <param name="RegistrationEndpoint">The URL of the OP describing the registration endpoint.</param>
        /// <param name="clientMetadata">The OIDCClientInformation object describing the client information to
        /// be submitted to the OP for registration.</param>
        /// <param name="TokenEndpointAuthMethod">(optional) the endpoint authentication method used to
        /// authenticate the client with the OP sever (if not specified using "client_secret_basic".</param>
        /// <returns>An oject describing all client information as returned by the OP server after
        /// registration.</returns>
        /// <exception cref="OpenIDClient.OIDCException">Thrown when an error occurs while registering
        /// the client with the OP.</exception>
        public OIDCClientInformation RegisterClient(string RegistrationEndpoint, OIDCClientInformation clientMetadata, string TokenEndpointAuthMethod = "client_secret_basic")
        {
            // Make registration request
            Dictionary<string, object> data = clientMetadata.SerializeToDictionary();
            OIDCClientRegistrationRequest registrationRequest = new OIDCClientRegistrationRequest();
            registrationRequest.DeserializeFromDictionary(data);

            // Check error and store client information from OP
            WebRequest request = WebRequest.Create(RegistrationEndpoint);
            string returnedString = WebOperations.PostUrlContent(request, registrationRequest, true);
            Dictionary<string, object> returnedJson = Deserializer.DeserializeFromJson<Dictionary<string, object>>(returnedString);
            if (returnedJson.Keys.Contains("error"))
            {
                OIDCResponseError error = new OIDCResponseError();
                throw new OIDCException("Error while registering client: " + error.Error + "\n" + error.ErrorDescription);
            }

            OIDCClientInformation clientInformation = new OIDCClientInformation();
            clientInformation.DeserializeFromDictionary(returnedJson);
            return clientInformation;
        }
コード例 #19
0
        public void Should_Request_And_Use_Unsigned_Id_Token()
        {
            rpid = "rp-id_token-sig_none";

            // givens
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";
            clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "code_flow_callback" };
            clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.Code };
            clientMetadata.IdTokenSignedResponseAlg = "none";
            OIDCClientInformation clientInformation = rp.RegisterClient(registrationEndopoint, clientMetadata);

            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = clientInformation.ClientId;
            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid };
            requestMessage.ResponseType = new List<ResponseType>() { ResponseType.Code };
            requestMessage.RedirectUri = clientInformation.RedirectUris[0];
            requestMessage.Nonce = WebOperations.RandomString();
            requestMessage.State = WebOperations.RandomString();
            requestMessage.Validate();

            rp.Authenticate(GetBaseUrl("/authorization"), requestMessage);
            semaphore.WaitOne();
            OIDCAuthCodeResponseMessage response = rp.ParseAuthCodeResponse(result, requestMessage.Scope, requestMessage.State);

            OIDCTokenRequestMessage tokenRequestMessage = new OIDCTokenRequestMessage();
            tokenRequestMessage.Scope = response.Scope;
            tokenRequestMessage.State = response.State;
            tokenRequestMessage.Code = response.Code;
            tokenRequestMessage.ClientId = clientInformation.ClientId;
            tokenRequestMessage.ClientSecret = clientInformation.ClientSecret;
            tokenRequestMessage.GrantType = "authorization_code";
            tokenRequestMessage.RedirectUri = clientInformation.RedirectUris[0];

            // when
            OIDCTokenResponseMessage tokenResponse = rp.SubmitTokenRequest(GetBaseUrl("/token"), tokenRequestMessage, clientInformation);

            // then
            Assert.NotNull(tokenResponse.IdToken);
            OIDCIdToken idToken = tokenResponse.GetIdToken();
            idToken.Validate();
        }
コード例 #20
0
        public void Should_Request_And_Use_Signed_And_Encrypted_Id_Token()
        {
            rpid = "rp-id_token-sig+enc";
            signalg = "RS256";
            encalg = "RSA1_5:A128CBC-HS256";

            // given
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            string registrationEndopoint = GetBaseUrl("/registration");
            OIDCClientInformation clientMetadata = new OIDCClientInformation();
            clientMetadata.ApplicationType = "web";
            clientMetadata.RedirectUris = new List<string>() { myBaseUrl + "code_flow_callback" };
            clientMetadata.ResponseTypes = new List<ResponseType>() { ResponseType.Code };
            clientMetadata.IdTokenEncryptedResponseAlg = "RSA1_5";
            clientMetadata.IdTokenEncryptedResponseEnc = "A128CBC-HS256";
            clientMetadata.JwksUri = myBaseUrl + "my_public_keys.jwks";
            OIDCClientInformation clientInformation = rp.RegisterClient(registrationEndopoint, clientMetadata);

            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = clientInformation.ClientId;
            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid };
            requestMessage.ResponseType = new List<ResponseType>() { ResponseType.Code };
            requestMessage.RedirectUri = clientInformation.RedirectUris[0];
            requestMessage.Nonce = WebOperations.RandomString();
            requestMessage.State = WebOperations.RandomString();
            requestMessage.Validate();

            rp.Authenticate(GetBaseUrl("/authorization"), requestMessage);
            semaphore.WaitOne();
            OIDCAuthCodeResponseMessage response = rp.ParseAuthCodeResponse(result, requestMessage.Scope, requestMessage.State);

            OIDCTokenRequestMessage tokenRequestMessage = new OIDCTokenRequestMessage();
            tokenRequestMessage.Scope = response.Scope;
            tokenRequestMessage.State = response.State;
            tokenRequestMessage.Code = response.Code;
            tokenRequestMessage.ClientId = clientInformation.ClientId;
            tokenRequestMessage.ClientSecret = clientInformation.ClientSecret;
            tokenRequestMessage.GrantType = "authorization_code";
            tokenRequestMessage.RedirectUri = clientInformation.RedirectUris[0];

            X509Certificate2 signCert = new X509Certificate2("server.pfx", "", X509KeyStorageFlags.Exportable);
            X509Certificate2 encCert = new X509Certificate2("server.pfx", "", X509KeyStorageFlags.Exportable);
            List<OIDCKey> myKeys = KeyManager.GetKeysJwkList(signCert, encCert);

            // when
            OIDCTokenResponseMessage tokenResponse = rp.SubmitTokenRequest(GetBaseUrl("/token"), tokenRequestMessage, clientInformation);

            // then
            Assert.NotNull(tokenResponse.IdToken);
            OIDCIdToken idToken = tokenResponse.GetIdToken(providerMetadata.Keys, null, myKeys);
            idToken.Validate();
        }