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); }
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); }
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; }
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); }
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); }
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)); }