public ValueTask <LogoutModel> LogoutCallback(IdentityHttpRequest request) { var callbackBinding = Saml2Binding.GetBindingForRequest(request, BindingDirection.Response); callbackBinding.ValidateSignature(identityProviderCert, true); callbackBinding.ValidateFields(new string[] { redirectUrl }); var callbackDocument = new Saml2LogoutResponse(callbackBinding); SamlIDManager.Validate(serviceProvider, callbackDocument.InResponseTo); if (String.IsNullOrWhiteSpace(callbackDocument.Issuer)) { return(new ValueTask <LogoutModel>((LogoutModel)null)); } var logout = new LogoutModel() { ServiceProvider = callbackDocument.Issuer, State = null, OtherClaims = null }; return(new ValueTask <LogoutModel>(logout)); }
internal Saml2FormBinding(IdentityHttpRequest request, BindingDirection bindingDirection) { this.BindingDirection = bindingDirection; string samlEncoded = this.BindingDirection switch { BindingDirection.Request => request.Form[Saml2Names.RequestParameterName], BindingDirection.Response => request.Form[Saml2Names.ResponseParameterName], _ => throw new NotImplementedException(), }; var samlRequestDecoded = DecodeSaml(samlEncoded); this.Document = new XmlDocument(); this.Document.LoadXml(samlRequestDecoded); this.HasSignature = X509XmlSigner.HasSignature(this.Document.DocumentElement); if (this.HasSignature) { this.SignatureAlgorithm = X509XmlSigner.GetSignatureAlgorithm(this.Document.DocumentElement); this.DigestAlgorithm = X509XmlSigner.GetDigestAlgorithm(this.Document.DocumentElement); } this.HasEncryption = X509XmlEncryptor.HasEncryptedDataElements(this.Document.DocumentElement); if (this.HasEncryption) { this.EncryptionAlgorithm = X509XmlEncryptor.GetEncryptionAlgorithm(this.Document.DocumentElement); } }
internal Saml2QueryBinding(IdentityHttpRequest request, BindingDirection bindingDirection) { this.BindingDirection = bindingDirection; string samlEncoded = this.BindingDirection switch { BindingDirection.Request => request.Query[Saml2Names.RequestParameterName], BindingDirection.Response => request.Query[Saml2Names.ResponseParameterName], _ => throw new NotImplementedException(), }; //var relayState = (string)request.Query[Saml2Names.RelayStateParameterName]; var sigAlg = (string)request.Query[Saml2Names.SignatureAlgorithmParameterName]; this.Signature = request.Query[Saml2Names.SignatureParameterName]; this.singingInput = request.QueryString.Substring(1, request.QueryString.IndexOf("&" + Saml2Names.SignatureParameterName + "=") - 1); if (samlEncoded == null) { return; } var samlRequestDecoded = DecodeSaml(samlEncoded); this.Document = new XmlDocument(); this.Document.LoadXml(samlRequestDecoded); this.SignatureAlgorithm = Algorithms.GetSignatureAlgorithmFromUrl(sigAlg); }
internal OpenIDQueryBinding(IdentityHttpRequest request, BindingDirection bindingDirection) { this.BindingDirection = bindingDirection; this.Document = new JObject(); foreach (var queryItem in request.Query) { this.Document.Add(queryItem.Key, JToken.FromObject((string)queryItem.Value)); } }
internal OAuth2FormBinding(IdentityHttpRequest request, BindingDirection bindingDirection) { this.BindingDirection = bindingDirection; this.Document = new JObject(); foreach (var formItem in request.Form) { this.Document.Add(formItem.Key, JToken.FromObject((string)formItem.Value)); } }
public static OAuth2Binding GetBindingForRequest(IdentityHttpRequest request, BindingDirection flowDirection) { if (request.HasFormContentType) { return(new OAuth2FormBinding(request, flowDirection)); } else { return(new OAuth2QueryBinding(request, flowDirection)); } }
public static bool IsOAuth2Binding(IdentityHttpRequest request) { if (request.HasFormContentType) { return(request.Form.Keys.Contains(OAuth2Binding.ClientFormName)); } else { return(request.Query.Keys.Contains(OAuth2Binding.ClientFormName)); } }
public static Saml2Binding GetBindingForRequest(IdentityHttpRequest request, BindingDirection bindingDirection) { if (request.HasFormContentType) { return(new Saml2FormBinding(request, bindingDirection)); } else { return(new Saml2QueryBinding(request, bindingDirection)); } }
public static bool IsSaml2Binding(IdentityHttpRequest request) { if (request.HasFormContentType) { return(request.Form.Keys.Contains(Saml2Names.RequestParameterName) || request.Form.Keys.Contains(Saml2Names.ResponseParameterName)); } else { return(request.Query.Keys.Contains(Saml2Names.RequestParameterName) || request.Query.Keys.Contains(Saml2Names.ResponseParameterName)); } }
public static bool IsCodeBinding(IdentityHttpRequest request) { if (request.HasFormContentType) { return(request.Form.Keys.Contains("code")); } else { return(request.Query.Keys.Contains("code")); } }
public ValueTask <LogoutModel> LogoutCallback(IdentityHttpRequest request) { var callbackBinding = OpenIDBinding.GetBindingForRequest(request, BindingDirection.Response); var callbackDocument = new OpenIDLogoutResponse(callbackBinding); var logout = new LogoutModel() { ServiceProvider = serviceProvider, State = callbackDocument.State, OtherClaims = callbackDocument.OtherClaims }; return(new ValueTask <LogoutModel>(logout)); }
internal OpenIDJwtQueryBinding(IdentityHttpRequest request, BindingDirection bindingDirection) { this.BindingDirection = bindingDirection; string token; if (request.Query.ContainsKey(OpenIDJwtBinding.IdTokenFormName)) { token = request.Query[OpenIDJwtBinding.IdTokenFormName]; accessToken = token; } else if (request.Query.ContainsKey(OpenIDJwtBinding.AccessTokenFormName)) { token = request.Query[OpenIDJwtBinding.AccessTokenFormName]; accessToken = token; } else { throw new IdentityProviderException("Missing JWT Token"); } var parts = token.Split(OpenIDJwtQueryBinding.tokenDelimiter); var jwtHeaderString = DecodeJwt(parts[0]); var jwtPayloadString = DecodeJwt(parts[1]); if (!String.IsNullOrWhiteSpace(parts[2])) { this.Signature = parts[2]; } this.singingInput = parts[0] + OpenIDJwtQueryBinding.tokenDelimiter + parts[1]; var jwtHeader = JsonConvert.DeserializeObject <JwtHeader>(jwtHeaderString); DeserializeJwtPayload(jwtPayloadString); foreach (var queryValue in request.Query) { this.Document.Add(queryValue.Key, (string)queryValue.Value); } if (!this.Document.ContainsKey(nameof(JwtHeader.X509Thumbprint)) && jwtHeader.X509Thumbprint != null) { this.Document.Add(nameof(JwtHeader.X509Thumbprint), JToken.FromObject(jwtHeader.X509Thumbprint)); } this.SignatureAlgorithm = Algorithms.GetSignatureAlgorithmFromJwt(jwtHeader.Algorithm); }
public ValueTask <IdentityModel> LoginCallback(IdentityHttpRequest request) { var callbackBinding = Saml2Binding.GetBindingForRequest(request, BindingDirection.Response); callbackBinding.ValidateSignature(identityProviderCert, true); callbackBinding.Decrypt(serviceProviderCert, requiredEncryption); callbackBinding.ValidateFields(new string[] { redirectUrl }); var callbackDocument = new Saml2AuthnResponse(callbackBinding); SamlIDManager.Validate(serviceProvider, callbackDocument.InResponseTo); if (callbackDocument.Audience != serviceProvider) { throw new IdentityProviderException("Saml Audience is not valid", String.Format("Received: {0}, Expected: {1}", serviceProvider, callbackDocument.Audience)); } if (String.IsNullOrWhiteSpace(callbackDocument.UserID)) { return(new ValueTask <IdentityModel>((IdentityModel)null)); } var identity = new IdentityModel() { UserID = callbackDocument.UserID, UserName = callbackDocument.UserName, Name = callbackDocument.UserName, Roles = callbackDocument.Roles, ServiceProvider = callbackDocument.Issuer, State = null, OtherClaims = null }; return(new ValueTask <IdentityModel>(identity)); }
public async ValueTask <IdentityModel> LoginCallback(IdentityHttpRequest request) { OpenIDJwtBinding callbackBinding; if (OpenIDJwtBinding.IsCodeBinding(request)) { var callbackCodeBinding = OpenIDBinding.GetBindingForRequest(request, BindingDirection.Response); var callbackCodeDocument = new OpenIDLoginResponse(callbackCodeBinding); if (!String.IsNullOrWhiteSpace(callbackCodeDocument.Error)) { throw new IdentityProviderException($"{callbackCodeDocument.Error}: {callbackCodeDocument.ErrorDescription}"); } //Get Token-------------------- var requestTokenDocument = new OpenIDTokenRequest(callbackCodeDocument.AccessCode, this.secret, OpenIDGrantType.authorization_code, redirectUrl); var requestTokenBinding = OpenIDBinding.GetBindingForDocument(requestTokenDocument, BindingType.Form); var requestTokenBody = requestTokenBinding.GetContent(); var requestToken = WebRequest.Create(tokenUrl); requestToken.Method = "POST"; requestToken.ContentType = "application/x-www-form-urlencoded"; var requestTokenBodyBytes = Encoding.UTF8.GetBytes(requestTokenBody); requestToken.ContentLength = requestTokenBodyBytes.Length; using (var stream = await requestToken.GetRequestStreamAsync()) { #if NETSTANDARD2_0 || NET461_OR_GREATER await stream.WriteAsync(requestTokenBodyBytes, 0, requestTokenBodyBytes.Length); #else await stream.WriteAsync(requestTokenBodyBytes.AsMemory()); #endif await stream.FlushAsync(); } WebResponse responseToken; try { responseToken = await requestToken.GetResponseAsync(); } catch (WebException ex) { if (ex.Response == null) { throw ex; } var responseTokenStream = ex.Response.GetResponseStream(); var error = await new StreamReader(responseTokenStream).ReadToEndAsync(); ex.Response.Close(); ex.Response.Dispose(); throw new IdentityProviderException(error); } //access_code is a JWT callbackBinding = OpenIDJwtBinding.GetBindingForResponse(responseToken, BindingDirection.Response); } else { callbackBinding = OpenIDJwtBinding.GetBindingForRequest(request, BindingDirection.Response); } var callbackDocument = new OpenIDLoginResponse(callbackBinding); if (!String.IsNullOrWhiteSpace(callbackDocument.Error)) { throw new IdentityProviderException($"{callbackDocument.Error}: {callbackDocument.ErrorDescription}"); } NonceManager.Validate(serviceProvider, callbackDocument.Nonce); if (callbackDocument.Audience != serviceProvider) { throw new IdentityProviderException("OpenID Audience is not valid", $"Received: {serviceProvider}, Expected: {callbackDocument.Audience}"); } var keys = await GetSignaturePublicKeys(this.identityProviderCertUrl); var key = keys.FirstOrDefault(x => x.X509Thumbprint == callbackDocument.X509Thumbprint); if (key == null) { key = keys.FirstOrDefault(x => x.KeyID == callbackDocument.KeyID); } if (key == null) { throw new IdentityProviderException("Identity Provider OpenID certificate not found from Json Key Url"); } if (key.KeyType != "RSA") { throw new IdentityProviderException("Identity Provider OpenID only supporting RSA at the moment"); } RSA rsa; if (key.X509Certificates == null || key.X509Certificates.Length == 0) { var rsaParams = new RSAParameters() { Modulus = Base64UrlEncoder.FromBase64String(key.Modulus), Exponent = Base64UrlEncoder.FromBase64String(key.Exponent) }; rsa = RSA.Create(); rsa.ImportParameters(rsaParams); } else { var certString = key.X509Certificates.First(); var certBytes = Convert.FromBase64String(certString); var cert = new X509Certificate2(certBytes); rsa = cert.GetRSAPublicKey(); } callbackBinding.ValidateSignature(rsa, requiredSignature); callbackBinding.ValidateFields(); var identity = new IdentityModel() { UserID = callbackDocument.UserID, UserName = callbackDocument.UserName ?? callbackDocument.Emails?.FirstOrDefault(), Name = callbackDocument.Name, Roles = callbackDocument.Roles, ServiceProvider = callbackDocument.Issuer, OtherClaims = callbackDocument.OtherClaims, State = callbackDocument.State, AccessToken = callbackBinding.AccessToken, }; return(identity); }
public async ValueTask <IdentityModel> LoginCallback(IdentityHttpRequest request) { var callbackBinding = OAuth2Binding.GetBindingForRequest(request, BindingDirection.Response); var callbackDocument = new OAuth2LoginResponse(callbackBinding); var callbackServiceProvider = callbackDocument.ServiceProvider; var code = callbackDocument.AccessCode; if (code == null) { return(null); } if (serviceProvider != callbackServiceProvider) { throw new IdentityProviderException("Service Providers do not match", $"Received: {serviceProvider}, Expected: {callbackServiceProvider}"); } //Get Token-------------------- var requestTokenDocument = new OAuth2TokenRequest(serviceProvider, code); var requestTokenBinding = OAuth2Binding.GetBindingForDocument(requestTokenDocument, BindingType.Query); var requestTokenAction = requestTokenBinding.GetResponse(tokenUrl); var requestToken = WebRequest.Create(requestTokenAction.RedirectUrl); var responseToken = await requestToken.GetResponseAsync(); var responseTokenBinding = OAuth2Binding.GetBindingForResponse(responseToken, BindingDirection.Response); var responseTokenDocument = new OAuth2TokenResponse(responseTokenBinding); //Get Identity--------------- var requestIdentityDocument = new OAuth2IdentityRequest(serviceProvider, responseTokenDocument.Token); var requestIdentityBinding = OAuth2Binding.GetBindingForDocument(requestIdentityDocument, BindingType.Query); var requestIdentityAction = requestIdentityBinding.GetResponse(identityUrl); var requestIdentity = WebRequest.Create(requestIdentityAction.RedirectUrl); var responseIdentity = await requestIdentity.GetResponseAsync(); var responseIdentityBinding = OAuth2Binding.GetBindingForResponse(responseIdentity, BindingDirection.Response); var responseIdentityDocument = new OAuth2IdentityResponse(responseIdentityBinding); if (responseIdentityDocument.ServiceProvider != serviceProvider) { return(null); } if (String.IsNullOrWhiteSpace(responseIdentityDocument.UserID)) { return(null); } var identity = new IdentityModel() { UserID = responseIdentityDocument.UserID, UserName = responseIdentityDocument.UserName, Name = responseIdentityDocument.UserName, ServiceProvider = responseIdentityDocument.ServiceProvider, Roles = responseIdentityDocument.Roles, OtherClaims = null, State = null, AccessToken = responseTokenDocument.Token }; return(identity); }