public void Should_Nonce_Be_Present_In_Implicit()
        {
            rpid = "rp-nonce-unless_code_flow";

            // given
            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = clientInformation.ClientId;

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

            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid };
            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();

            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            rp.Authenticate(GetBaseUrl("/authorization"), requestMessage);
            semaphore.WaitOne();
            OIDCAuthImplicitResponseMessage response = rp.ParseAuthImplicitResponse(result, requestMessage.Scope, requestMessage.State);
            OIDCIdToken idToken = response.GetIdToken(providerMetadata.Keys, clientInformation.ClientSecret);

            // then
            idToken.Validate();
        }
        public void Should_Spport_Third_Party_Initiated_Login()
        {
            rpid = "rp-support_3rd_party_init_login";

            // given
            OIDCThirdPartyLoginRequest thirdPartyRequest = new OIDCThirdPartyLoginRequest();
            thirdPartyRequest.Iss = GetBaseUrl("/");
            WebRequest webRequest = WebRequest.Create(clientInformation.InitiateLoginUri + "?" + thirdPartyRequest.SerializeToQueryString());

            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.Validate();
            request = requestMessage.SerializeToQueryString();

            param = providerMetadata.AuthorizationEndpoint;

            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            WebOperations.GetUrlContent(webRequest);
            semaphore.WaitOne();
            OIDCAuthCodeResponseMessage response = rp.ParseAuthCodeResponse(result);

            // then
            response.Validate();
        }
        private OIDCAuthorizationRequestMessage generateRequestMessage(OpenIDProviderData providerData, OpenIDUrls urls)
        {
            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = providerData.ClientInformation.ClientId;
            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid, MessageScope.Profile };
            requestMessage.ResponseType = new List<ResponseType>() { ResponseType.Code };
            requestMessage.RedirectUri = urls.CodeCallbackCommand.ToString();
            requestMessage.State = WebOperations.RandomString();
            requestMessage.Nonce = WebOperations.RandomString();
            requestMessage.Validate();

            return requestMessage;
        }
        public void Should_Authenticate_With_Claims_In_Scope_Basic()
        {
            rpid = "rp-scope-userinfo_claims";

            // given
            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = clientInformation.ClientId;

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

            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid, MessageScope.Profile, MessageScope.Email, MessageScope.Address, MessageScope.Phone };
            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();

            OpenIdRelyingParty rp = new OpenIdRelyingParty();

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

            OIDCUserInfoRequestMessage userInfoRequestMessage = new OIDCUserInfoRequestMessage();
            userInfoRequestMessage.Scope = authResponse.Scope;
            userInfoRequestMessage.State = authResponse.State;

            // when
            OIDCUserInfoResponseMessage response = rp.GetUserInfo(GetBaseUrl("/userinfo"), userInfoRequestMessage, authResponse.AccessToken);

            // then
            response.Validate();
            Assert.IsNotNullOrEmpty(response.Name);
            Assert.IsNotNullOrEmpty(response.GivenName);
            Assert.IsNotNullOrEmpty(response.FamilyName);
            Assert.IsNotNullOrEmpty(response.Email);
            Assert.IsNotNull(response.Address);
            Assert.IsNotNullOrEmpty(response.Address.StreetAddress);
            Assert.IsNotNullOrEmpty(response.Address.PostalCode);
            Assert.IsNotNullOrEmpty(response.Address.Locality);
            Assert.IsNotNullOrEmpty(response.Address.Country);
            Assert.IsNotNullOrEmpty(response.PhoneNumber);
        }
 /// <summary>
 /// Method that sends authentication request to the OP.
 /// </summary>
 /// <param name="AuthenticateUrl">The URL to be used for the authentication request.</param>
 /// <param name="RequestMessage">The reuqest message to be sent to the OP.</param>
 /// <param name="Certificate">The certificate to be used, in case of a self-issued authentication.</param>
 /// <returns>The authentication response from the OP.</returns>
 public OIDCAuthImplicitResponseMessage Authenticate(string AuthenticateUrl, OIDCAuthorizationRequestMessage RequestMessage, X509Certificate2 Certificate = null)
 {
     if (new Uri(AuthenticateUrl).Scheme == "openid")
     {
         // we are dealing with a Self-Issued OpenID provider
         Dictionary<string, object> response = PerformSelfIssuedAuthentication(RequestMessage, Certificate);
         OIDCAuthImplicitResponseMessage responseMessage = new OIDCAuthImplicitResponseMessage();
         responseMessage.DeserializeFromDictionary(response);
         return responseMessage;
     }
     else
     {
         string login_url = AuthenticateUrl + "?" + RequestMessage.SerializeToQueryString();
         WebOperations.GetUrlContent(WebRequest.Create(login_url));
         return null;
     }
 }
        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 OIDClientSerializableMessage GetAuthResponse(ResponseType RespType, string Nonce = null, bool Profile = false, OIDClaims Claims = null)
        {
            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = clientInformation.ClientId;
            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid };
            requestMessage.RedirectUri = clientInformation.RedirectUris[0];
            requestMessage.Nonce = (Nonce == null) ? WebOperations.RandomString() : Nonce;
            requestMessage.State = WebOperations.RandomString();
            requestMessage.Claims = Claims;

            if (Profile)
            {
                requestMessage.Scope.Add(MessageScope.Profile);
                requestMessage.Scope.Add(MessageScope.Address);
                requestMessage.Scope.Add(MessageScope.Phone);
                requestMessage.Scope.Add(MessageScope.Email);
            }

            if (ResponseType.Code == RespType)
            {
                requestMessage.ResponseType = new List<ResponseType>() { ResponseType.Code };
            }
            else if (ResponseType.IdToken == RespType)
            {
                requestMessage.ResponseType = new List<ResponseType>() { ResponseType.IdToken, ResponseType.Token };
            }

            requestMessage.Validate();

            OpenIdRelyingParty rp = new OpenIdRelyingParty();
            rp.Authenticate(GetBaseUrl("/authorization"), requestMessage);
            semaphore.WaitOne();
            if (ResponseType.Code == RespType)
            {
                return rp.ParseAuthCodeResponse(result, requestMessage.Scope, requestMessage.State);
            }
            else if (ResponseType.IdToken == RespType)
            {
                return rp.ParseAuthImplicitResponse(result, requestMessage.Scope, requestMessage.State);
            }

            throw new Exception("Error in parameter passed");
        }
        public void Should_Authenticate_With_Code_Response_Type()
        {
            rpid = "rp-response_type-code";

            // given
            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.Validate();

            OpenIdRelyingParty rp = new OpenIdRelyingParty();

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

            // then
            response.Validate();
        }
        public void Should_Authenticate_With_IdToken_Response_Type()
        {
            rpid = "rp-response_type-id_token";

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

            OpenIdRelyingParty rp = new OpenIdRelyingParty();

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

            // then
            response.Validate();
        }
        public void Should_OpenId_Missing_Scope_Throw_Exception()
        {
            rpid = "rp-scope-contains_openid_scope";

            // given
            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.Scope = new List<MessageScope>() { MessageScope.Phone };

            // when
            requestMessage.Validate();

            // then
        }
 /// <summary>
 /// Method to perform third party initiated login.
 /// </summary>
 /// <param name="queryString">The query string representation of the authentication request</param>
 /// <param name="authEndpoint">The OP authorization endpoint</param>
 public void ThirdPartyInitiatedLogin(OIDCAuthorizationRequestMessage requestMessage, string authEndpoint)
 {
     string login_url = authEndpoint + "?" + requestMessage.SerializeToQueryString();
     WebOperations.GetUrlContent(WebRequest.Create(login_url));
 }
        public void Should_Nonce_Be_Present_In_Self_Issued()
        {
            rpid = "rp-nonce-unless_code_flow";
            WebRequest.RegisterPrefix("openid", new OIDCWebRequestCreate());

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

            X509Certificate2 certificate = new X509Certificate2("server.pfx", "", X509KeyStorageFlags.Exportable);
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            OIDCAuthImplicitResponseMessage response = rp.Authenticate("openid://", requestMessage, certificate);
            OIDCIdToken idToken = response.GetIdToken();

            // then
            response.Validate();
        }
        public void Should_Authenticate_With_Claims_In_Scope_Self_Issued()
        {
            rpid = "rp-scope-userinfo_claims";
            WebRequest.RegisterPrefix("openid", new OIDCWebRequestCreate());

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

            X509Certificate2 certificate = new X509Certificate2("server.pfx", "", X509KeyStorageFlags.Exportable);
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            OIDCAuthImplicitResponseMessage response = rp.Authenticate("openid://", requestMessage, certificate);
            OIDCIdToken idToken = response.GetIdToken();

            // then
            response.Validate();
            rp.ValidateIdToken(idToken, clientInformation, idToken.Iss, requestMessage.Nonce);
            Assert.IsNotNullOrEmpty(idToken.Name);
            Assert.IsNotNullOrEmpty(idToken.GivenName);
            Assert.IsNotNullOrEmpty(idToken.FamilyName);
            Assert.IsNotNullOrEmpty(idToken.Email);
            Assert.IsNotNull(idToken.Address);
            Assert.IsNotNullOrEmpty(idToken.Address.StreetAddress);
            Assert.IsNotNullOrEmpty(idToken.Address.PostalCode);
            Assert.IsNotNullOrEmpty(idToken.Address.Locality);
            Assert.IsNotNullOrEmpty(idToken.Address.Country);
            Assert.IsNotNullOrEmpty(idToken.PhoneNumber);
        }
        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();
        }
        private static void ThirdPartyInitiatedLoginCallback(IHttpContext context)
        {
            result = context.Request.Uri.Query;
            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.DeserializeFromQueryString(request);

            OpenIdRelyingParty rp = new OpenIdRelyingParty();
            rp.ThirdPartyInitiatedLogin(requestMessage, param);
        }
        public void Should_Reject_Id_Token_With_Incorrect_C_Hash()
        {
            rpid = "rp-id_token-bad_c_hash";

            // givens
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

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

            rp.Authenticate(GetBaseUrl("/authorization"), requestMessage);
            semaphore.WaitOne();

            // when
            OIDCAuthCodeResponseMessage response = rp.ParseAuthCodeResponse(result, requestMessage.Scope, requestMessage.State);

            // then
            Assert.NotNull(response.IdToken);
            OIDCIdToken idToken = response.GetIdToken(providerMetadata.Keys);
            string ExpectedCHash = response.GetExpectedHash(response.Code, providerMetadata.Keys);
            idToken.Validate(GetBaseUrl("/"), clientInformation.ClientId, ExpectedCHash, null);
        }
        private OIDCAuthorizationRequestMessage generateRequestObject(OpenIDProviderData providerData, OpenIDUrls urls, string state, string nonce)
        {
            OIDCAuthorizationRequestMessage requestObject = new OIDCAuthorizationRequestMessage();
            requestObject.Iss = providerData.ClientInformation.ClientId;
            requestObject.Aud = providerData.ProviderMatadata.Issuer;
            requestObject.ClientId = providerData.ClientInformation.ClientId;
            requestObject.Scope = new List<MessageScope>() { MessageScope.Openid, MessageScope.Profile };
            requestObject.ResponseType = new List<ResponseType>() { ResponseType.Code };
            requestObject.RedirectUri = urls.CodeCallbackCommand.ToString();
            requestObject.State = state;
            requestObject.Nonce = nonce;
            requestObject.Validate();

            return requestObject;
        }
        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);
        }
        public void Should_Authenticate_With_IdToken_Token_Response_Type_Post()
        {
            rpid = "rp-response_mode-form_post";

            // given
            OIDCAuthorizationRequestMessage requestMessage = new OIDCAuthorizationRequestMessage();
            requestMessage.ClientId = clientInformation.ClientId;
            requestMessage.Scope = new List<MessageScope>() { MessageScope.Openid };
            requestMessage.ResponseType = new List<ResponseType>() { ResponseType.IdToken, ResponseType.Token };
            requestMessage.ResponseMode = "form_post";
            requestMessage.RedirectUri = clientInformation.RedirectUris[1];
            requestMessage.Nonce = WebOperations.RandomString();
            requestMessage.State = WebOperations.RandomString();
            requestMessage.Validate();

            string login_url = GetBaseUrl("/authorization") + "?" + requestMessage.SerializeToQueryString();
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            Dictionary<string, object> html = WebOperations.GetUrlContent(WebRequest.Create(login_url), false);

            // then
            Assert.NotNull(html);
            CollectionAssert.Contains(html.Keys, "body");
            string textHtml = (string)html["body"];
            Assert.NotNull(textHtml);
            HtmlDocument document = new HtmlDocument();
            document.LoadHtml(textHtml);
            HtmlNode formNode = document.DocumentNode.SelectNodes("//form")[0];
            Assert.NotNull(formNode);
            Assert.AreEqual(formNode.Attributes["method"].Value.ToLower(), "post");
            Assert.AreEqual(formNode.Attributes["action"].Value.ToLower(), requestMessage.RedirectUri);

            bool hasIdTokenInput = false;
            foreach (HtmlNode innode in formNode.SelectNodes("//input"))
            {
                if (innode.Attributes["name"].Value.Equals("access_token"))
                {
                    hasIdTokenInput = true;
                }
            }
            Assert.IsTrue(hasIdTokenInput);
        }
        private OIDCAuthorizationRequestMessage generateRequestObject(string state, string nonce)
        {
            OIDCAuthorizationRequestMessage requestObject = new OIDCAuthorizationRequestMessage();
            requestObject.Iss = clientInformation.ClientId;
            requestObject.Aud = opBaseurl.ToString();
            requestObject.ClientId = clientInformation.ClientId;
            requestObject.Scope = new List<MessageScope>() { MessageScope.Openid };
            requestObject.ResponseType = new List<ResponseType>() { ResponseType.Code };
            requestObject.RedirectUri = clientInformation.RedirectUris[0];
            requestObject.State = state;
            requestObject.Nonce = nonce;
            requestObject.Validate();

            return requestObject;
        }
        private OIDCAuthorizationRequestMessage generateRequestMessage()
        {
            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.State = WebOperations.RandomString();
            requestMessage.Nonce = WebOperations.RandomString();
            requestMessage.RequestUri = myBaseUrl + "request.jwt";
            requestMessage.Validate();

            return requestMessage;
        }
        private Dictionary<string, object> PerformSelfIssuedAuthentication(OIDCAuthorizationRequestMessage requestMessage, X509Certificate2 certificate)
        {
            OIDCIdToken idToken = new OIDCIdToken();
            idToken.Iss = "https://self-issued.me";
            idToken.Sub = Convert.ToBase64String(Encoding.UTF8.GetBytes(certificate.Thumbprint));
            idToken.Aud = new List<string>() { requestMessage.RedirectUri };
            idToken.Nonce = requestMessage.Nonce;
            idToken.Exp = DateTime.MaxValue;
            idToken.Iat = DateTime.MaxValue;
            idToken.SubJkw = KeyManager.GetOIDCKey(certificate, "RSA", "AQAB", "sig");

            if (requestMessage.Scope.Contains(MessageScope.Profile))
            {
                idToken.GivenName = "Myself";
                idToken.FamilyName = "User";
                idToken.Name = idToken.GivenName + " " + idToken.FamilyName;
            }

            if (requestMessage.Scope.Contains(MessageScope.Email))
            {
                idToken.Email = "*****@*****.**";
            }

            if (requestMessage.Scope.Contains(MessageScope.Address))
            {
                idToken.Address = new OIDCAddress();
                idToken.Address.Country = "Italy";
                idToken.Address.PostalCode = "20100";
                idToken.Address.StreetAddress = "Via Test, 1";
                idToken.Address.Locality = "Milano";
            }

            if (requestMessage.Scope.Contains(MessageScope.Phone))
            {
                idToken.PhoneNumber = "0";
            }

            idToken.Validate();

            Dictionary<string, object> responseMessage = new Dictionary<string, object>();
            responseMessage["id_token"] = JWT.Encode(idToken.SerializeToJsonString(), null, JwsAlgorithm.none);
            responseMessage["state"] = requestMessage.State;

            return responseMessage;
        }
        private OIDCAuthorizationRequestMessage generateRequestMessage(bool UseRequestUri = false, string state = null, string nonce = null)
        {
            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.State = (state != null) ? state : WebOperations.RandomString();
            requestMessage.Nonce = (nonce != null) ? nonce : WebOperations.RandomString();
            if (UseRequestUri)
            {
                requestMessage.RequestUri = myBaseUrl + "request.jwt";
            }
            requestMessage.Validate();

            return requestMessage;
        }
        public void Should_Reject_Id_Token_With_Invalid_ES256_Signature()
        {
            rpid = "rp-id_token-bad_es256_sig";

            // givens
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

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

            // Manipulate keys to make them invalid
            List<OIDCKey> manipulatedKeys = new List<OIDCKey>();
            foreach (OIDCKey curKey in providerMetadata.Keys)
            {
                OIDCKey newKey = curKey.Clone() as OIDCKey;
                if (curKey.N != null)
                {
                    StringBuilder strBuilder = new StringBuilder(newKey.N);
                    strBuilder[17] = (char)(newKey.N[17] + 1);
                    newKey.N = strBuilder.ToString();
                }
                manipulatedKeys.Add(newKey);
            }

            rp.Authenticate(GetBaseUrl("/authorization"), requestMessage);
            semaphore.WaitOne();

            // when
            OIDCAuthImplicitResponseMessage response = rp.ParseAuthImplicitResponse(result, requestMessage.Scope, requestMessage.State);

            // then
            Assert.NotNull(response.IdToken);
            OIDCIdToken idToken = response.GetIdToken(manipulatedKeys);
            idToken.Validate();
        }
        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();
        }
        public void Should_Authenticate_With_Self_Issued_Provider()
        {
            rpid = "rp-response_type-self_issued";
            WebRequest.RegisterPrefix("openid", new OIDCWebRequestCreate());

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

            X509Certificate2 certificate = new X509Certificate2("server.pfx", "", X509KeyStorageFlags.Exportable);
            OpenIdRelyingParty rp = new OpenIdRelyingParty();

            // when
            OIDCAuthImplicitResponseMessage response = rp.Authenticate("openid://", requestMessage, certificate);

            // then
            OIDCIdToken idToken = response.GetIdToken();

            //The Client MUST validate that the aud (audience) Claim contains the value of the
            //redirect_uri that the Client sent in the Authentication Request as an audience.
            CollectionAssert.Contains(idToken.Aud, requestMessage.RedirectUri);

            //If a nonce value was sent in the Authentication Request, a nonce Claim MUST be present
            //and its value checked to verify that it is the same value as the one that was sent in
            //the Authentication Request.
            Assert.AreEqual(requestMessage.Nonce, idToken.Nonce);
        }