예제 #1
0
 private void RemoveSamlUpPartyCertificate(GeneralSamlUpPartyViewModel generalSamlUpParty, CertificateInfoViewModel certificateInfo)
 {
     generalSamlUpParty.Form.ClearFieldError(nameof(generalSamlUpParty.Form.Model.Keys));
     if (generalSamlUpParty.Form.Model.Keys.Remove(certificateInfo.Key))
     {
         generalSamlUpParty.CertificateInfoList.Remove(certificateInfo);
     }
 }
예제 #2
0
 private void SamlUpPartyViewModelAfterInit(GeneralSamlUpPartyViewModel samlUpParty, SamlUpPartyViewModel model)
 {
     if (samlUpParty.CreateMode)
     {
         model.Claims = new List <string> {
             "*"
         };
     }
 }
예제 #3
0
 private void SamlUpPartyViewModelAfterInit(GeneralSamlUpPartyViewModel samlUpParty, SamlUpPartyViewModel model)
 {
     if (samlUpParty.CreateMode)
     {
         model.Claims = new List <string> {
             ClaimTypes.Email, ClaimTypes.Name, ClaimTypes.GivenName, ClaimTypes.Surname
         };
     }
 }
예제 #4
0
        private async Task OnSamlUpPartyCertificateFileSelectedAsync(GeneralSamlUpPartyViewModel generalSamlUpParty, IFileListEntry[] files)
        {
            if (generalSamlUpParty.Form.Model.Keys == null)
            {
                generalSamlUpParty.Form.Model.Keys = new List <JsonWebKey>();
            }
            generalSamlUpParty.Form.ClearFieldError(nameof(generalSamlUpParty.Form.Model.Keys));
            foreach (var file in files)
            {
                if (file.Size > GeneralSamlUpPartyViewModel.CertificateMaxFileSize)
                {
                    generalSamlUpParty.Form.SetFieldError(nameof(generalSamlUpParty.Form.Model.Keys), $"That's too big. Max size: {GeneralSamlUpPartyViewModel.CertificateMaxFileSize} bytes.");
                    return;
                }

                generalSamlUpParty.CertificateFileStatus = "Loading...";

                using (var memoryStream = new MemoryStream())
                {
                    await file.Data.CopyToAsync(memoryStream);

                    try
                    {
                        var certificate = new X509Certificate2(memoryStream.ToArray());
                        var jwk         = await certificate.ToFTJsonWebKeyAsync();

                        if (generalSamlUpParty.Form.Model.Keys.Any(k => k.X5t.Equals(jwk.X5t, StringComparison.OrdinalIgnoreCase)))
                        {
                            generalSamlUpParty.Form.SetFieldError(nameof(generalSamlUpParty.Form.Model.Keys), "Signature validation keys (certificates) has duplicates.");
                            return;
                        }

                        generalSamlUpParty.CertificateInfoList.Add(new CertificateInfoViewModel
                        {
                            Subject    = certificate.Subject,
                            ValidFrom  = certificate.NotBefore,
                            ValidTo    = certificate.NotAfter,
                            IsValid    = certificate.IsValid(),
                            Thumbprint = certificate.Thumbprint,
                            Key        = jwk
                        });
                        generalSamlUpParty.Form.Model.Keys.Add(jwk);
                    }
                    catch (Exception ex)
                    {
                        generalSamlUpParty.Form.SetFieldError(nameof(generalSamlUpParty.Form.Model.Keys), ex.Message);
                    }
                }

                generalSamlUpParty.CertificateFileStatus = GeneralSamlUpPartyViewModel.DefaultCertificateFileStatus;
            }
        }
예제 #5
0
        private async Task OnSamlUpPartyCertificateFileSelectedAsync(GeneralSamlUpPartyViewModel generalSamlUpParty, IFileListEntry[] files)
        {
            if (generalSamlUpParty.Form.Model.Keys == null)
            {
                generalSamlUpParty.Form.Model.Keys = new List <JwtWithCertificateInfo>();
            }
            generalSamlUpParty.Form.ClearFieldError(nameof(generalSamlUpParty.Form.Model.Keys));
            foreach (var file in files)
            {
                if (file.Size > GeneralSamlUpPartyViewModel.CertificateMaxFileSize)
                {
                    generalSamlUpParty.Form.SetFieldError(nameof(generalSamlUpParty.Form.Model.Keys), $"That's too big. Max size: {GeneralSamlUpPartyViewModel.CertificateMaxFileSize} bytes.");
                    return;
                }

                generalSamlUpParty.CertificateFileStatus = "Loading...";

                using (var memoryStream = new MemoryStream())
                {
                    await file.Data.CopyToAsync(memoryStream);

                    try
                    {
                        var base64UrlEncodeCertificate = WebEncoders.Base64UrlEncode(memoryStream.ToArray());
                        var jwtWithCertificateInfo     = await HelpersService.ReadCertificateAsync(new CertificateAndPassword { EncodeCertificate = base64UrlEncodeCertificate });

                        if (generalSamlUpParty.Form.Model.Keys.Any(k => k.X5t.Equals(jwtWithCertificateInfo.X5t, StringComparison.OrdinalIgnoreCase)))
                        {
                            generalSamlUpParty.Form.SetFieldError(nameof(generalSamlUpParty.Form.Model.Keys), "Signature validation keys (certificates) has duplicates.");
                            return;
                        }

                        generalSamlUpParty.KeyInfoList.Add(new KeyInfoViewModel
                        {
                            Subject    = jwtWithCertificateInfo.CertificateInfo.Subject,
                            ValidFrom  = jwtWithCertificateInfo.CertificateInfo.ValidFrom,
                            ValidTo    = jwtWithCertificateInfo.CertificateInfo.ValidTo,
                            IsValid    = jwtWithCertificateInfo.CertificateInfo.IsValid(),
                            Thumbprint = jwtWithCertificateInfo.CertificateInfo.Thumbprint,
                            Key        = jwtWithCertificateInfo
                        });
                        generalSamlUpParty.Form.Model.Keys.Add(jwtWithCertificateInfo);
                    }
                    catch (Exception ex)
                    {
                        generalSamlUpParty.Form.SetFieldError(nameof(generalSamlUpParty.Form.Model.Keys), ex.Message);
                    }
                }

                generalSamlUpParty.CertificateFileStatus = GeneralSamlUpPartyViewModel.DefaultCertificateFileStatus;
            }
        }
예제 #6
0
        private SamlUpPartyViewModel ToViewModel(GeneralSamlUpPartyViewModel generalSamlUpParty, SamlUpParty samlUpParty)
        {
            return(samlUpParty.Map <SamlUpPartyViewModel>(afterMap =>
            {
                if (samlUpParty.UpdateState == PartyUpdateStates.Manual)
                {
                    afterMap.IsManual = true;
                }

                if (samlUpParty.UpdateState == PartyUpdateStates.AutomaticStopped)
                {
                    afterMap.AutomaticStopped = true;
                }
                else
                {
                    afterMap.AutomaticStopped = false;
                }

                afterMap.EnableSingleLogout = !samlUpParty.DisableSingleLogout;

                if (samlUpParty.AuthnContextComparison.HasValue)
                {
                    afterMap.AuthnContextComparisonViewModel = (SamlAuthnContextComparisonTypesVievModel)Enum.Parse(typeof(SamlAuthnContextComparisonTypesVievModel), samlUpParty.AuthnContextComparison.Value.ToString());
                }
                else
                {
                    afterMap.AuthnContextComparisonViewModel = SamlAuthnContextComparisonTypesVievModel.Null;
                }

                generalSamlUpParty.KeyInfoList.Clear();
                foreach (var key in afterMap.Keys)
                {
                    generalSamlUpParty.KeyInfoList.Add(new KeyInfoViewModel
                    {
                        Subject = key.CertificateInfo.Subject,
                        ValidFrom = key.CertificateInfo.ValidFrom,
                        ValidTo = key.CertificateInfo.ValidTo,
                        IsValid = key.CertificateInfo.IsValid(),
                        Thumbprint = key.CertificateInfo.Thumbprint,
                        Key = key
                    });
                }

                if (afterMap.ClaimTransforms?.Count > 0)
                {
                    afterMap.ClaimTransforms = afterMap.ClaimTransforms.MapClaimTransforms();
                }
            }));
        }
예제 #7
0
        private async Task DeleteSamlUpPartyAsync(GeneralSamlUpPartyViewModel generalSamlUpParty)
        {
            try
            {
                await UpPartyService.DeleteSamlUpPartyAsync(generalSamlUpParty.Name);

                UpParties.Remove(generalSamlUpParty);
                await OnStateHasChanged.InvokeAsync(UpParty);
            }
            catch (TokenUnavailableException)
            {
                await(OpenidConnectPkce as TenantOpenidConnectPkce).TenantLoginAsync();
            }
            catch (Exception ex)
            {
                generalSamlUpParty.Form.SetError(ex.Message);
            }
        }
예제 #8
0
        public void ShowSamlTab(GeneralSamlUpPartyViewModel downParty, SamlTabTypes samlTabTypes)
        {
            switch (samlTabTypes)
            {
            case SamlTabTypes.Saml:
                downParty.ShowSamlTab           = true;
                downParty.ShowClaimTransformTab = false;
                break;

            case SamlTabTypes.ClaimsTransform:
                downParty.ShowSamlTab           = false;
                downParty.ShowClaimTransformTab = true;
                break;

            default:
                throw new NotSupportedException();
            }
        }
예제 #9
0
 private void ShowCreateUpParty(PartyTypes type)
 {
     if (type == PartyTypes.Login)
     {
         var loginUpParty = new GeneralLoginUpPartyViewModel();
         loginUpParty.CreateMode = true;
         loginUpParty.Edit       = true;
         upParties.Add(loginUpParty);
     }
     else if (type == PartyTypes.Oidc)
     {
         var oidcUpParty = new GeneralOidcUpPartyViewModel();
         oidcUpParty.CreateMode = true;
         oidcUpParty.Edit       = true;
         upParties.Add(oidcUpParty);
     }
     else if (type == PartyTypes.Saml2)
     {
         var samlUpParty = new GeneralSamlUpPartyViewModel();
         samlUpParty.CreateMode = true;
         samlUpParty.Edit       = true;
         upParties.Add(samlUpParty);
     }
 }
예제 #10
0
        private async Task OnEditSamlUpPartyValidSubmitAsync(GeneralSamlUpPartyViewModel generalSamlUpParty, EditContext editContext)
        {
            try
            {
                if (generalSamlUpParty.Form.Model.ClaimTransforms?.Count() > 0)
                {
                    foreach (var claimTransform in generalSamlUpParty.Form.Model.ClaimTransforms)
                    {
                        if (claimTransform is SamlClaimTransformClaimInViewModel claimTransformClaimIn && !claimTransformClaimIn.ClaimIn.IsNullOrWhiteSpace())
                        {
                            claimTransform.ClaimsIn = new List <string> {
                                claimTransformClaimIn.ClaimIn
                            };
                        }
                    }
                }

                var samlUpParty = generalSamlUpParty.Form.Model.Map <SamlUpParty>(afterMap =>
                {
                    afterMap.DisableSingleLogout = !generalSamlUpParty.Form.Model.EnableSingleLogout;

                    afterMap.AuthnBinding = new SamlBinding {
                        RequestBinding = generalSamlUpParty.Form.Model.AuthnRequestBinding, ResponseBinding = generalSamlUpParty.Form.Model.AuthnResponseBinding
                    };
                    if (!afterMap.LogoutUrl.IsNullOrEmpty())
                    {
                        afterMap.LogoutBinding = new SamlBinding {
                            RequestBinding = generalSamlUpParty.Form.Model.LogoutRequestBinding, ResponseBinding = generalSamlUpParty.Form.Model.LogoutResponseBinding
                        };
                    }
                    if (afterMap.ClaimTransforms?.Count() > 0)
                    {
                        int order = 1;
                        foreach (var claimTransform in afterMap.ClaimTransforms)
                        {
                            claimTransform.Order = order++;
                        }
                    }
                });

                if (generalSamlUpParty.CreateMode)
                {
                    await UpPartyService.CreateSamlUpPartyAsync(samlUpParty);
                }
                else
                {
                    await UpPartyService.UpdateSamlUpPartyAsync(samlUpParty);
                }
                generalSamlUpParty.Name = generalSamlUpParty.Form.Model.Name;
                generalSamlUpParty.Edit = false;
                await OnStateHasChanged.InvokeAsync(UpParty);
            }
            catch (FoxIDsApiException ex)
            {
                if (ex.StatusCode == System.Net.HttpStatusCode.Conflict)
                {
                    generalSamlUpParty.Form.SetFieldError(nameof(generalSamlUpParty.Form.Model.Name), ex.Message);
                }
                else
                {
                    throw;
                }
            }
        }
예제 #11
0
        private async Task OnEditSamlUpPartyValidSubmitAsync(GeneralSamlUpPartyViewModel generalSamlUpParty, EditContext editContext)
        {
            try
            {
                if (generalSamlUpParty.Form.Model.ClaimTransforms?.Count() > 0)
                {
                    foreach (var claimTransform in generalSamlUpParty.Form.Model.ClaimTransforms)
                    {
                        if (claimTransform is SamlClaimTransformClaimInViewModel claimTransformClaimIn && !claimTransformClaimIn.ClaimIn.IsNullOrWhiteSpace())
                        {
                            claimTransform.ClaimsIn = new List <string> {
                                claimTransformClaimIn.ClaimIn
                            };
                        }
                    }
                }

                var samlUpParty = generalSamlUpParty.Form.Model.Map <SamlUpParty>(afterMap =>
                {
                    afterMap.DisableSingleLogout = !generalSamlUpParty.Form.Model.EnableSingleLogout;

                    if (generalSamlUpParty.Form.Model.AuthnContextComparisonViewModel != SamlAuthnContextComparisonTypesVievModel.Null)
                    {
                        afterMap.AuthnContextComparison = (SamlAuthnContextComparisonTypes)Enum.Parse(typeof(SamlAuthnContextComparisonTypes), generalSamlUpParty.Form.Model.AuthnContextComparisonViewModel.ToString());
                    }

                    if (generalSamlUpParty.Form.Model.IsManual)
                    {
                        afterMap.UpdateState = PartyUpdateStates.Manual;
                    }
                    else
                    {
                        afterMap.UpdateState = PartyUpdateStates.Automatic;
                    }

                    if (afterMap.ClaimTransforms?.Count() > 0)
                    {
                        int order = 1;
                        foreach (var claimTransform in afterMap.ClaimTransforms)
                        {
                            claimTransform.Order = order++;
                        }
                    }
                });

                if (generalSamlUpParty.CreateMode)
                {
                    var samlUpPartyResult = await UpPartyService.CreateSamlUpPartyAsync(samlUpParty);

                    generalSamlUpParty.Form.UpdateModel(ToViewModel(generalSamlUpParty, samlUpPartyResult));
                    generalSamlUpParty.CreateMode = false;
                    toastService.ShowSuccess("SAML 2.0 Up-party created.", "SUCCESS");
                }
                else
                {
                    var samlUpPartyResult = await UpPartyService.UpdateSamlUpPartyAsync(samlUpParty);

                    generalSamlUpParty.Form.UpdateModel(ToViewModel(generalSamlUpParty, samlUpPartyResult));
                    toastService.ShowSuccess("SAML 2.0 Up-party updated.", "SUCCESS");
                }
                generalSamlUpParty.Name = generalSamlUpParty.Form.Model.Name;
            }
            catch (FoxIDsApiException ex)
            {
                if (ex.StatusCode == System.Net.HttpStatusCode.Conflict)
                {
                    generalSamlUpParty.Form.SetFieldError(nameof(generalSamlUpParty.Form.Model.Name), ex.Message);
                }
                else
                {
                    throw;
                }
            }
        }
예제 #12
0
        private async Task OnReadMetadataFileAsync(GeneralSamlUpPartyViewModel generalSamlUpParty)
        {
            generalSamlUpParty.Form.ClearError();
            try
            {
                var files = await fileReaderService.CreateReference(readMetadataFileElement).EnumerateFilesAsync();

                var file = files.FirstOrDefault();
                if (file == null)
                {
                    return;
                }

                string metadataXml;
                await using (var stream = await file.OpenReadAsync())
                {
                    byte[] resultBytes = new byte[stream.Length];
                    await stream.ReadAsync(resultBytes, 0, (int)stream.Length);

                    metadataXml = Encoding.ASCII.GetString(resultBytes);
                }

                var samlUpParty = await UpPartyService.ReadSamlUpPartyMetadataAsync(new SamlReadMetadataRequest { Type = SamlReadMetadataType.Xml, Metadata = metadataXml });

                generalSamlUpParty.Form.Model.Issuer   = samlUpParty.Issuer;
                generalSamlUpParty.Form.Model.AuthnUrl = samlUpParty.AuthnUrl;
                if (samlUpParty.AuthnRequestBinding.HasValue)
                {
                    generalSamlUpParty.Form.Model.AuthnRequestBinding = samlUpParty.AuthnRequestBinding.Value;
                }

                generalSamlUpParty.Form.Model.LogoutUrl = samlUpParty.LogoutUrl;
                if (!string.IsNullOrEmpty(samlUpParty.SingleLogoutResponseUrl))
                {
                    generalSamlUpParty.Form.Model.SingleLogoutResponseUrl = samlUpParty.SingleLogoutResponseUrl;
                }
                if (samlUpParty.LogoutRequestBinding.HasValue)
                {
                    generalSamlUpParty.Form.Model.LogoutRequestBinding = samlUpParty.LogoutRequestBinding.Value;
                }

                generalSamlUpParty.KeyInfoList     = new List <KeyInfoViewModel>();
                generalSamlUpParty.Form.Model.Keys = new List <JwtWithCertificateInfo>();

                if (samlUpParty.Keys?.Count() > 0)
                {
                    foreach (var key in samlUpParty.Keys)
                    {
                        generalSamlUpParty.KeyInfoList.Add(new KeyInfoViewModel
                        {
                            Subject    = key.CertificateInfo.Subject,
                            ValidFrom  = key.CertificateInfo.ValidFrom,
                            ValidTo    = key.CertificateInfo.ValidTo,
                            IsValid    = key.CertificateInfo.IsValid(),
                            Thumbprint = key.CertificateInfo.Thumbprint,
                            Key        = key
                        });
                        generalSamlUpParty.Form.Model.Keys.Add(key);
                    }
                }

                generalSamlUpParty.Form.Model.SignAuthnRequest = samlUpParty.SignAuthnRequest;
            }
            catch (Exception ex)
            {
                generalSamlUpParty.Form.SetError($"Failing SAML 2.0 metadata. {ex.Message}");
            }
        }