private string ObtainIssuer(string hostname, string resource) { string query = "/.well-known/webfinger?resource=" + resource + "&rel=http://openid.net/specs/connect/1.0/issuer"; WebRequest webRequest = WebRequest.Create(hostname + query); Dictionary <string, object> o = WebOperations.GetUrlContent(webRequest); if ((DateTime)o["expires"] < DateTime.UtcNow - new TimeSpan(0, 10, 0)) { throw new OIDCException("Claims expired on " + o["expires"]); } if ((string)o["subject"] != resource) { throw new OIDCException("Claims released for a different subject."); } string issuer = null; JArray links = (JArray)o["links"]; foreach (JToken link in links) { Dictionary <string, object> dic = link.ToObject <Dictionary <string, object> >(); if (dic["rel"] as string == "http://openid.net/specs/connect/1.0/issuer") { issuer = dic["href"] as string; } } if (issuer == null) { throw new OIDCException("No issuer found in claims returned."); } return(issuer); }
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]; } } } } }
/// <summary> /// Method that queries the OP server to obtain the OpenID configuration. /// </summary> /// <param name="hostname">The hostname of the OP to be queried.</param> /// <param name="expectedIssuer">(optional) the issuer expected from the OP configuration. /// This information can come, for instance, from a previous issuer discovery process /// via webfinger.</param> /// <returns>An oject describing all relevant properties of the OP.</returns> /// <exception cref="OpenIDClient.OIDCException">Thrown when the returned message from server /// is not valid or if wrong issuer is found in the answer.</exception> public OIDCProviderMetadata ObtainProviderInformation(string hostname, string expectedIssuer = null) { string query = "/.well-known/openid-configuration"; WebRequest webRequest = WebRequest.Create(hostname + query); Dictionary <string, object> o = WebOperations.GetUrlContent(webRequest); OIDCProviderMetadata providerMetadata = new OIDCProviderMetadata(o); if (expectedIssuer != null && !expectedIssuer.Equals(providerMetadata.Issuer)) { throw new OIDCException("Wrong issuer, discarding configuration"); } return(providerMetadata); }
/// <summary> /// Constructor deserializing message properties from dictionary. /// </summary> /// <param name="o">The dictionary object containing message properties.</param> public OIDCProviderMetadata(Dictionary <string, object> o) { DeserializeFromDictionary(o); if (JwksUri != null) { Keys = new List <OIDCKey>(); Dictionary <string, object> jwks = WebOperations.GetUrlContent(WebRequest.Create(JwksUri)); JArray keys = (JArray)jwks["keys"]; foreach (JToken key in keys) { OIDCKey newKey = new OIDCKey(key.ToObject <Dictionary <string, object> >()); Keys.Add(newKey); } } }
/// <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); } }
/// <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)); }
/// <summary> /// <see cref="OIDClientSerializableMessage.Validate()"/> /// </summary> public override void Validate() { if (RedirectUris != null && ResponseTypes != null && RedirectUris.Count != ResponseTypes.Count) { throw new OIDCException("The redirect_uris do not match response_types."); } if (RedirectUris != null && SectorIdentifierUri != null) { List <string> siUris = new List <string>(); dynamic uris = WebOperations.GetUrlContent(WebRequest.Create(SectorIdentifierUri)); foreach (string uri in uris) { siUris.Add(uri); } foreach (string uri in RedirectUris) { if (!siUris.Contains(uri)) { throw new OIDCException("The sector_identifier_uri json must include URIs from the redirect_uri array."); } } } if (ResponseTypes != null && GrantTypes != null) { foreach (ResponseType responseType in ResponseTypes) { if ((responseType == ResponseType.Code && !GrantTypes.Contains("authorization_code")) || (responseType == ResponseType.IdToken && !GrantTypes.Contains("implicit")) || (responseType == ResponseType.Token && !GrantTypes.Contains("implicit"))) { throw new OIDCException("The response_types do not match grant_types."); } } } List <string> listUri = new List <string>() { LogoUri, ClientUri, PolicyUri, TosUri, JwksUri, SectorIdentifierUri, InitiateLoginUri, RegistrationClientUri }; if (RedirectUris != null) { listUri.AddRange(RedirectUris); } if (RequestUris != null) { listUri.AddRange(RequestUris); } foreach (string uri in listUri) { if (uri == null) { continue; } if (new Uri(uri).Scheme != "https") { throw new OIDCException("Some of the URIs for the client is not on https"); } } }