public CommandResult Run(HttpRequestData request, IOptions options, HttpSessionState session)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var urls = new OpenIDUrls(options.RPOptions, request.ApplicationUrl);

            OIDCAuthCodeResponseMessage authResponse  = GetAuthResponse(request, session);
            OIDCTokenResponseMessage    tokenResponse = GetToken(authResponse, options, session, urls.CodeCallbackCommand.ToString());

            OIDCUserInfoRequestMessage  userInfoRequestMessage = new OIDCUserInfoRequestMessage();
            OIDCUserInfoResponseMessage userInfoResponse       = GetUserInfo(authResponse, options, session, tokenResponse.AccessToken);

            var    principal = GetPrincipal(userInfoResponse, options, session);
            string ReturnUrl = request.QueryString["ReturnUrl"].FirstOrDefault() ?? urls.ApplicationBase.ToString();

            return(new CommandResult()
            {
                HttpStatusCode = HttpStatusCode.SeeOther,
                Location = new Uri(ReturnUrl),
                Principal = principal
            });
        }
        /// <summary>
        /// Get user information from the OP after user authentication
        /// </summary>
        /// <param name="url">The url to be used to retrieve user information</param>
        /// <param name="userInfoRequestMessage">The user info request message</param>
        /// <param name="accessToken">The access token obtain during authentication</param>
        /// <returns>The response message containing user information</returns>
        public OIDCUserInfoResponseMessage GetUserInfo(string url, OIDCUserInfoRequestMessage userInfoRequestMessage, string accessToken, string idTokenSub = null, bool bearer = true, string ClientSecret = null, List <OIDCKey> RPKeys = null)
        {
            WebRequest request;

            if (bearer)
            {
                request = WebRequest.Create(url);
                request.Headers.Add("Authorization", "Bearer " + accessToken);
            }
            else
            {
                request = WebRequest.Create(url + "?access_token=" + accessToken);
            }
            string returnedString = WebOperations.PostUrlContent(request, userInfoRequestMessage);
            string jsonToken      = userInfoRequestMessage.CheckSignatureAndDecryptJWT(returnedString, null, ClientSecret, RPKeys);
            Dictionary <string, object> returnedJson = Deserializer.DeserializeFromJson <Dictionary <string, object> >(jsonToken);

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

            OIDCUserInfoResponseMessage userInfoResponse = new OIDCUserInfoResponseMessage();

            userInfoResponse.DeserializeFromDictionary(returnedJson);

            if (idTokenSub != null && userInfoResponse.Sub != idTokenSub)
            {
                throw new OIDCException("Wrong sub in UserInfo, it does not match idToken's.");
            }

            return(userInfoResponse);
        }
        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);
        }
        private ClaimsPrincipal GetPrincipal(OIDCUserInfoResponseMessage userInfoResponse, IOptions options, HttpSessionState session)
        {
            OpenIDProviderData providerData = options.OpenIDProviders[session["op"] as string];
            string             issuer       = providerData.ProviderMatadata.Issuer;

            List <Claim> c = new List <Claim>();

            if (userInfoResponse.Name != null)
            {
                c.Add(new Claim(ClaimTypes.Name, userInfoResponse.Name, ClaimValueTypes.String, issuer));
            }
            if (userInfoResponse.FamilyName != null)
            {
                c.Add(new Claim(ClaimTypes.Surname, userInfoResponse.FamilyName, ClaimValueTypes.String, issuer));
            }
            if (userInfoResponse.GivenName != null)
            {
                c.Add(new Claim(ClaimTypes.GivenName, userInfoResponse.GivenName, ClaimValueTypes.String, issuer));
            }
            if (userInfoResponse.Email != null)
            {
                c.Add(new Claim(ClaimTypes.Email, userInfoResponse.Email, ClaimValueTypes.String, issuer));
            }
            if (userInfoResponse.Gender != null)
            {
                c.Add(new Claim(ClaimTypes.Gender, userInfoResponse.Gender, ClaimValueTypes.String, issuer));
            }
            c.Add(new Claim(ClaimTypes.Role, "User"));

            ClaimsIdentity  ci        = new ClaimsIdentity(c, "OpenIDAuthentication", ClaimTypes.Name, ClaimTypes.Role);
            ClaimsPrincipal principal = new ClaimsPrincipal(ci);

            return(options.RPOptions.SystemIdentityModelIdentityConfiguration.ClaimsAuthenticationManager.Authenticate(null, principal));
        }
        public static void ParseAggregatedClaims(OIDCUserInfoResponseMessage obj, Dictionary <string, object> data)
        {
            if (data.ContainsKey("_claim_names") && data["_claim_names"] != null)
            {
                Dictionary <string, object> claims = (data["_claim_names"] as JObject).ToObject <Dictionary <string, object> >();
                foreach (KeyValuePair <string, object> kvp in claims)
                {
                    string name = kvp.Key;
                    string path = kvp.Value.ToString();

                    if (!data.ContainsKey("_claim_sources") || data["_claim_sources"] == null)
                    {
                        continue;
                    }

                    dynamic sources = data["_claim_sources"];
                    foreach (JProperty s in sources)
                    {
                        if (s.Name != path)
                        {
                            continue;
                        }

                        dynamic vals = s.Value;
                        foreach (JProperty v in sources)
                        {
                            Dictionary <string, object> values = null;
                            Dictionary <string, object> val    = (v.Value as JObject).ToObject <Dictionary <string, object> >();

                            if (val.ContainsKey("JWT"))
                            {
                                string json = JWT.Decode(val["JWT"].ToString());
                                values = DeserializeFromJson <Dictionary <string, object> >(json);
                            }
                            else if (val.ContainsKey("endpoint"))
                            {
                                WebRequest req = WebRequest.Create(val["endpoint"].ToString());
                                if (val.ContainsKey("access_token"))
                                {
                                    req.Headers.Add("Authorization", "Bearer " + val["access_token"].ToString());
                                }
                                values = WebOperations.GetUrlContent(req);
                            }

                            if (!values.ContainsKey(name))
                            {
                                continue;
                            }

                            if (obj.CustomClaims == null)
                            {
                                obj.CustomClaims = new Dictionary <string, object>();
                            }
                            obj.CustomClaims[name] = values[name];
                        }
                    }
                }
            }
        }
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        public void implicitFlowCallback(HttpListenerRequest req, HttpListenerResponse res, HTTPSession session)
        {
            // Callback redirect URI
            //String url = req.url() + "#" + req.queryParams("url_fragment");

            // TODO parse authentication response from url
            // TODO validate the ID Token according to the OpenID Connect spec (sec 3.2.2.11.)

            // TODO set the appropriate values
            string      authCode    = null;
            string      accessToken = null;
            OIDCIdToken idToken     = null;
            OIDCUserInfoResponseMessage userInfoResponse = null;
        }
Example #9
0
        public OIDCUserInfoResponseMessage GetUserInfo(string url, OIDCUserInfoRequestMessage userInfoRequestMessage, string accessToken)
        {
            WebRequest request = WebRequest.Create(url);

            request.Headers.Add("Authorization", "Bearer " + accessToken);
            Dictionary <string, object> returnedJson = PostUrlContent(request, userInfoRequestMessage);

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

            OIDCUserInfoResponseMessage userInfoResponse = new OIDCUserInfoResponseMessage();

            userInfoResponse.deserializeFromDynamic(returnedJson);
            return(userInfoResponse);
        }
        public void Should_Not_Send_AccessToken()
        {
            rpid = "rp-user_info-not_query";

            // given
            OIDClaims requestClaims = new OIDClaims();

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

            OIDCAuthImplicitResponseMessage authResponse = (OIDCAuthImplicitResponseMessage)GetAuthResponse(ResponseType.IdToken, null, true, requestClaims);

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

            // then
            response.Validate();
            Assert.IsNotNullOrEmpty(response.Name);
        }
Example #11
0
        public void codeFlowCallback(HttpListenerRequest req, HttpListenerResponse res, HTTPSession session)
        {
            // Callback redirect URI
            String queryString = req.Url.Query;

            // TODO parse authentication response from url
            // TODO make token request
            // TODO validate the ID Token according to the OpenID Connect spec (sec 3.1.3.7.)
            // TODO make userinfo request

            // TODO set the appropriate values
            string      authCode    = null;
            string      accessToken = null;
            OIDCIdToken idToken     = null;
            OIDCUserInfoResponseMessage userInfoResponse = null;

            string responsePage = WebServer.successPage(authCode, accessToken, idToken, userInfoResponse);

            WebServer.SendResponse(req, res, responsePage);
        }
        public void Should_Request_And_Use_Claims_Userinfo()
        {
            rpid = "rp-claims_request-userinfo_claims";
            GetProviderMetadata();

            // given
            OIDClaims requestClaims = new OIDClaims();

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

            OIDCAuthImplicitResponseMessage authResponse = (OIDCAuthImplicitResponseMessage)GetAuthResponse(ResponseType.IdToken, null, true, requestClaims);

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

            // then
            response.Validate();
            Assert.IsNotNullOrEmpty(response.Name);
        }
        public void Should_Use_Distributed_Claims()
        {
            rpid = "rp-claims-distributed";
            claims = "distributed";

            // given
            OpenIdRelyingParty rp = new OpenIdRelyingParty();
            string hostname = GetBaseUrl("/");
            providerMetadata = rp.ObtainProviderInformation(hostname);

            OIDCAuthCodeResponseMessage authResponse = GetAuthResponse(ResponseType.Code, null, true) as OIDCAuthCodeResponseMessage;
            OIDCTokenResponseMessage tokenResponse = GetToken(authResponse);
            OIDCUserInfoRequestMessage userInfoRequestMessage = new OIDCUserInfoRequestMessage();

            // when
            OIDCUserInfoResponseMessage userInfoResponse = GetUserInfo(authResponse.Scope, authResponse.State, tokenResponse.AccessToken);

            // then
            Assert.NotNull(userInfoResponse);
            Assert.AreEqual(userInfoResponse.CustomClaims["age"], 30);
        }
        public void Should_Reject_Userinfo_With_Invalid_Sub()
        {
            rpid = "rp-user_info-bad_sub_claim";

            // given
            OIDClaims requestClaims = new OIDClaims();

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

            OIDCAuthImplicitResponseMessage authResponse = (OIDCAuthImplicitResponseMessage)GetAuthResponse(ResponseType.IdToken, null, true, requestClaims);
            OIDCIdToken idToken = authResponse.GetIdToken(providerMetadata.Keys);

            idToken.Validate();

            // when
            OIDCUserInfoResponseMessage response = GetUserInfo(authResponse.Scope, authResponse.State, authResponse.AccessToken, idToken.Sub + "Wrong");

            // then
            response.Validate();
            Assert.IsNotNullOrEmpty(response.Name);
        }
Example #15
0
        public static string successPage(string authCode, string accessToken, OIDCIdToken idToken, OIDCUserInfoResponseMessage userInfoResponse)
        {
            string stringIdToken  = idToken.serializeToJsonString();
            string userInfoString = userInfoResponse.serializeToJsonString();
            String successPage    = File.ReadAllText(Path.Combine(Client.ROOT_PATH, "success_page.html"));

            return(String.Format(successPage, authCode, accessToken, stringIdToken, userInfoString));
        }