protected JsonDocument DecodeToken() { if (_decodedToken != null) { return(_decodedToken); } if (AccessToken == null) { throw new InvalidOperationException($"{nameof(AccessToken)} not found."); } var parts = AccessToken.Split('.'); if (parts.Length != 3) { throw new InvalidOperationException($"{nameof(AccessToken)} must have 3 parts"); } var decodedBytes = CoreHelpers.Base64UrlDecode(parts[1]); if (decodedBytes == null || decodedBytes.Length < 1) { throw new InvalidOperationException($"{nameof(AccessToken)} must have 3 parts"); } _decodedToken = JsonDocument.Parse(decodedBytes); return(_decodedToken); }
public JObject DecodeToken() { if (_decodedAccessToken != null) { return(_decodedAccessToken); } if (_accessTokenForDecoding == null) { throw new InvalidOperationException("Access token not found."); } var parts = _accessTokenForDecoding.Split('.'); if (parts.Length != 3) { throw new InvalidOperationException("JWT must have 3 parts."); } var decodedBytes = CoreHelpers.Base64UrlDecode(parts[1]); if (decodedBytes == null || decodedBytes.Length < 1) { throw new InvalidOperationException("Cannot decode the token."); } _decodedAccessToken = JObject.Parse(Encoding.UTF8.GetString(decodedBytes)); return(_decodedAccessToken); }
public async Task <IActionResult> Access(string id, [FromBody] SendAccessRequestModel model) { var guid = new Guid(CoreHelpers.Base64UrlDecode(id)); var(send, passwordRequired, passwordInvalid) = await _sendService.AccessAsync(guid, model.Password); if (passwordRequired) { return(new UnauthorizedResult()); } if (passwordInvalid) { await Task.Delay(2000); throw new BadRequestException("Invalid password."); } if (send == null) { throw new NotFoundException(); } var sendResponse = new SendAccessResponseModel(send, _globalSettings); if (send.UserId.HasValue) { var creator = await _userService.GetUserByIdAsync(send.UserId.Value); sendResponse.CreatorIdentifier = creator.Email; } return(new ObjectResult(sendResponse)); }
public async Task <IActionResult> GetSendFileDownloadData(string encodedSendId, string fileId, [FromBody] SendAccessRequestModel model) { var sendId = new Guid(CoreHelpers.Base64UrlDecode(encodedSendId)); var send = await _sendRepository.GetByIdAsync(sendId); if (send == null) { throw new BadRequestException("Could not locate send"); } var(url, passwordRequired, passwordInvalid) = await _sendService.GetSendFileDownloadUrlAsync(send, fileId, model.Password); if (passwordRequired) { return(new UnauthorizedResult()); } if (passwordInvalid) { await Task.Delay(2000); throw new BadRequestException("Invalid password."); } if (send == null) { throw new NotFoundException(); } return(new ObjectResult(new SendFileDownloadDataResponseModel() { Id = fileId, Url = url, })); }
private static readonly string _tag_log = "Fido2Builder"; // Tag for the logs in the Fido2Builder /// <summary> /// Build the request for Sign In using FIDO2 /// </summary> public static PublicKeyCredentialRequestOptions ParsePublicKeyCredentialRequestOptions(Dictionary <string, object> data) { PublicKeyCredentialRequestOptions.Builder builder = new PublicKeyCredentialRequestOptions.Builder(); foreach (KeyValuePair <string, object> entry in data) { switch (entry.Key) { case "challenge": // Challenge to be sign builder.SetChallenge(CoreHelpers.Base64UrlDecode((string)entry.Value)); break; case "allowCredentials": // List of FIDO2 Keys that already are registered to the user and should only use one of this FIDO2 Keys builder.SetAllowList(ParseCredentialDescriptors((List <Dictionary <string, object> >)entry.Value)); break; case "rpId": // Server ID information builder.SetRpId((string)entry.Value); break; case "timeout": // temp limit to sign in builder.SetTimeoutSeconds((Java.Lang.Double)(double) entry.Value); break; case "userVerification": // Require that user has to verify before using FIDO2 //Skip break; case "extensions": // Adicional parameter to improve even more the security //Skip break; } } return(builder.Build()); }
/// <summary> /// Build the part of request where contains the user information, exemple name and id /// </summary> public static PublicKeyCredentialUserEntity ParseUser(Fido2User data) { if (data == null) { return(null); } string id = null; string name = null; string icon = null; string displayName = null; if (data.Id != null && data.Id.Length > 0) { // id of user id = data.Id; } if (data.Name != null && data.Name.Length > 0) { // name of user name = data.Name; } if (data.Icon != null && data.Icon.Length > 0) { // icon of user icon = data.Icon; } if (data.DisplayName != null && data.DisplayName.Length > 0) { // name of user to display to the user displayName = data.DisplayName; } return(new PublicKeyCredentialUserEntity(CoreHelpers.Base64UrlDecode(id), name, icon, displayName)); }
/// <summary> /// Build the part of request where contains the user information, exemple name and id /// </summary> public static PublicKeyCredentialUserEntity ParseUser(Dictionary <string, string> data) { string id = null; string name = null; string icon = null; string displayName = null; foreach (KeyValuePair <string, string> entry in data) { switch (entry.Key) { case "id": // id of user id = entry.Value; break; case "name": // name of user name = entry.Value; break; case "icon": // icon of user icon = entry.Value; break; case "displayName": // name of user to display to the user displayName = entry.Value; break; } } return(new PublicKeyCredentialUserEntity(CoreHelpers.Base64UrlDecode(id), name, icon, displayName)); }
/// <summary> /// Build the request for Regist a New FIDO2 Key using FIDO2 /// </summary> public static PublicKeyCredentialCreationOptions ParsePublicKeyCredentialCreationOptions(Fido2RegistrationChallengeResponse data) { if (data == null) { return(null); } PublicKeyCredentialCreationOptions.Builder builder = new PublicKeyCredentialCreationOptions.Builder(); if (data.Challenge != null && data.Challenge.Length > 0) { // Challenge to be sign builder.SetChallenge(CoreHelpers.Base64UrlDecode(data.Challenge)); } if (data.ExcludeCredentials != null && data.ExcludeCredentials.Count > 0) { // List of FIDO2 Keys that already are registered to the user and shouldn't be excluded of registering again builder.SetExcludeList(ParseCredentialDescriptors(data.ExcludeCredentials)); } if (data.Timeout > 0) { // temp limit to regist a new key builder.SetTimeoutSeconds((Java.Lang.Double)data.Timeout); } if (data.User != null) { // User information builder.SetUser(ParseUser(data.User)); } if (data.Rp != null) { // Server information builder.SetRp(ParseRp(data.Rp)); } if (data.PubKeyCredParams != null) { //Algorithm information builder.SetParameters(ParseParameters(data.PubKeyCredParams)); } if (data.AuthenticatorSelection != null) { // Options of regist selected builder.SetAuthenticatorSelection(ParseSelection(data.AuthenticatorSelection)); } if (data.attestation != null) { // It is how the signature is given, anonymously or direct. //Skip } if (data.Extensions != null) { // Adicional parameter to improve even more the security //Skip } return(builder.Build()); }
/// <summary> /// Build the request for Regist a New FIDO2 Key using FIDO2 /// </summary> public static PublicKeyCredentialCreationOptions ParsePublicKeyCredentialCreationOptions(Dictionary <string, object> data) { PublicKeyCredentialCreationOptions.Builder builder = new PublicKeyCredentialCreationOptions.Builder(); foreach (KeyValuePair <string, object> entry in data) { switch (entry.Key) { case "user": // User information builder.SetUser(ParseUser((Dictionary <string, string>)entry.Value)); break; case "challenge": // Challenge to be sign builder.SetChallenge(CoreHelpers.Base64UrlDecode((string)entry.Value)); break; case "pubKeyCredParams": //Algorithm information builder.SetParameters(ParseParameters((List <Dictionary <string, object> >)entry.Value)); break; case "authenticatorSelection": // Options of regist selected builder.SetAuthenticatorSelection(ParseSelection((Dictionary <string, string>)entry.Value)); break; case "excludeCredentials": // List of FIDO2 Keys that already are registered to the user and shouldn't be excluded of registering again builder.SetExcludeList(ParseCredentialDescriptors((List <Dictionary <string, object> >)entry.Value)); break; case "rpId": // Server ID information builder.SetRp(new PublicKeyCredentialRpEntity((string)entry.Value, null, null)); break; case "rp": // Server information builder.SetRp(ParseRp((Dictionary <string, string>)entry.Value)); break; case "timeout": // temp limit to regist a new key builder.SetTimeoutSeconds((Java.Lang.Double)(double) entry.Value); break; case "userVerification": // Require that user has to verify before using FIDO2 //Skip break; case "attestation": //It is how the signature is given, anonymously or direct. //Skip break; } } return(builder.Build()); }
/// <summary> /// Build the part of request where contains the FIDO2 Key information /// </summary> public static List <PublicKeyCredentialDescriptor> ParseCredentialDescriptors(List <Fido2CredentialDescriptor> listData) { if (listData == null && listData.Count > 0) { return(new List <PublicKeyCredentialDescriptor>()); } List <PublicKeyCredentialDescriptor> credentials = new List <PublicKeyCredentialDescriptor>(); string id = null; string type = null; List <Transport> transports = null; foreach (Fido2CredentialDescriptor data in listData) { id = null; type = null; transports = new List <Transport>(); if (data.Id != null && data.Id.Length > 0) { // id of the FIDO2 key id = data.Id; } if (data.Type != null && data.Type.Length > 0) { // type of the FIDO2 key type = data.Type; } if (data.Transports != null && data.Transports.Count > 0) { // list of types of transport accepted (NFC, USB, INTERNAL, BLUETOOTH) of the FIDO2 key foreach (string transport in (List <string>)data.Transports) { transports.Add(Transport.FromString(transport)); } } credentials.Add(new PublicKeyCredentialDescriptor(type, CoreHelpers.Base64UrlDecode(id), transports)); } return(credentials); }
public async Task <IActionResult> GetSendFileDownloadData(string encodedSendId, string fileId, [FromBody] SendAccessRequestModel model) { // Uncomment whenever we want to require the `send-id` header //if (!_currentContext.HttpContext.Request.Headers.ContainsKey("Send-Id") || // _currentContext.HttpContext.Request.Headers["Send-Id"] != encodedSendId) //{ // throw new BadRequestException("Invalid Send-Id header."); //} var sendId = new Guid(CoreHelpers.Base64UrlDecode(encodedSendId)); var send = await _sendRepository.GetByIdAsync(sendId); if (send == null) { throw new BadRequestException("Could not locate send"); } var(url, passwordRequired, passwordInvalid) = await _sendService.GetSendFileDownloadUrlAsync(send, fileId, model.Password); if (passwordRequired) { return(new UnauthorizedResult()); } if (passwordInvalid) { await Task.Delay(2000); throw new BadRequestException("Invalid password."); } if (send == null) { throw new NotFoundException(); } return(new ObjectResult(new SendFileDownloadDataResponseModel() { Id = fileId, Url = url, })); }
private static readonly string _tag_log = "Fido2Builder"; // Tag for the logs in the Fido2Builder /// <summary> /// Build the request for Sign In using FIDO2 /// </summary> public static PublicKeyCredentialRequestOptions ParsePublicKeyCredentialRequestOptions(Fido2AuthenticationChallengeResponse data) { if (data == null) { return(null); } PublicKeyCredentialRequestOptions.Builder builder = new PublicKeyCredentialRequestOptions.Builder(); if (data.Challenge != null && data.Challenge.Length > 0) { // Challenge to be sign builder.SetChallenge(CoreHelpers.Base64UrlDecode(data.Challenge)); } if (data.AllowCredentials != null && data.AllowCredentials.Count > 0) { // List of FIDO2 Keys that already are registered to the user and should only use one of this FIDO2 Keys builder.SetAllowList(ParseCredentialDescriptors(data.AllowCredentials)); } if (data.RpId != null && data.RpId.Length > 0) { // Server ID information builder.SetRpId(data.RpId); } if (data.Timeout > 0) { // temp limit to sign in builder.SetTimeoutSeconds((Java.Lang.Double)data.Timeout); } if (data.UserVerification != null) { // Require that user has to verify before using FIDO2 //Skip } if (data.Extensions != null) { // Adicional parameter to improve even more the security //Skip } return(builder.Build()); }
public async Task <IActionResult> Access(string id, [FromBody] SendAccessRequestModel model) { // Uncomment whenever we want to require the `send-id` header //if (!_currentContext.HttpContext.Request.Headers.ContainsKey("Send-Id") || // _currentContext.HttpContext.Request.Headers["Send-Id"] != id) //{ // throw new BadRequestException("Invalid Send-Id header."); //} var guid = new Guid(CoreHelpers.Base64UrlDecode(id)); var(send, passwordRequired, passwordInvalid) = await _sendService.AccessAsync(guid, model.Password); if (passwordRequired) { return(new UnauthorizedResult()); } if (passwordInvalid) { await Task.Delay(2000); throw new BadRequestException("Invalid password."); } if (send == null) { throw new NotFoundException(); } var sendResponse = new SendAccessResponseModel(send, _globalSettings); if (send.UserId.HasValue && !send.HideEmail.GetValueOrDefault()) { var creator = await _userService.GetUserByIdAsync(send.UserId.Value); sendResponse.CreatorIdentifier = creator.Email; } return(new ObjectResult(sendResponse)); }
public async Task <IActionResult> Access(string id, [FromBody] SendAccessRequestModel model) { var guid = new Guid(CoreHelpers.Base64UrlDecode(id)); var(send, passwordRequired, passwordInvalid) = await _sendService.AccessAsync(guid, model.Password); if (passwordRequired) { return(new UnauthorizedResult()); } if (passwordInvalid) { await Task.Delay(2000); throw new BadRequestException("Invalid password."); } if (send == null) { throw new NotFoundException(); } return(new ObjectResult(new SendAccessResponseModel(send, _globalSettings))); }
/// <summary> /// Build the part of request where contains the FIDO2 Key information /// </summary> public static List <PublicKeyCredentialDescriptor> ParseCredentialDescriptors(List <Dictionary <string, object> > listData) { List <PublicKeyCredentialDescriptor> credentials = new List <PublicKeyCredentialDescriptor>(); string id = null; string type = null; List <Transport> transports = null; foreach (Dictionary <string, object> data in listData) { id = null; type = null; transports = new List <Transport>(); foreach (KeyValuePair <string, object> entry in data) { switch (entry.Key) { case "id": // id of the FIDO2 key id = (string)entry.Value; break; case "type": // type of the FIDO2 key type = (string)entry.Value; break; case "transports": // list of types of transport accepted (NFC, USB, INTERNAL, BLUETOOTH) of the FIDO2 key foreach (string transport in (List <string>)entry.Value) { transports.Add(Transport.FromString(transport)); } break; } } credentials.Add(new PublicKeyCredentialDescriptor(type, CoreHelpers.Base64UrlDecode(id), transports)); } return(credentials); }
public IEnumerable <ValidationResult> Validate(ValidationContext context) { var i18nService = context.GetService(typeof(II18nService)) as I18nService; if (ConfigType == SsoType.OpenIdConnect) { if (string.IsNullOrWhiteSpace(Authority)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("AuthorityValidationError"), new[] { nameof(Authority) })); } if (string.IsNullOrWhiteSpace(ClientId)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("ClientIdValidationError"), new[] { nameof(ClientId) })); } if (string.IsNullOrWhiteSpace(ClientSecret)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("ClientSecretValidationError"), new[] { nameof(ClientSecret) })); } } else if (ConfigType == SsoType.Saml2) { if (string.IsNullOrWhiteSpace(IdpEntityId)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("IdpEntityIdValidationError"), new[] { nameof(IdpEntityId) })); } if (IdpBindingType == Saml2BindingType.Artifact && string.IsNullOrWhiteSpace(IdpArtifactResolutionServiceUrl)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("Saml2BindingTypeValidationError"), new[] { nameof(IdpArtifactResolutionServiceUrl) })); } if (!Uri.IsWellFormedUriString(IdpEntityId, UriKind.Absolute) && string.IsNullOrWhiteSpace(IdpSingleSignOnServiceUrl)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlValidationError"), new[] { nameof(IdpSingleSignOnServiceUrl) })); } if (InvalidServiceUrl(IdpSingleSignOnServiceUrl)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleSignOnServiceUrlInvalid"), new[] { nameof(IdpSingleSignOnServiceUrl) })); } if (InvalidServiceUrl(IdpArtifactResolutionServiceUrl)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("IdpArtifactResolutionServiceUrlInvalid"), new[] { nameof(IdpArtifactResolutionServiceUrl) })); } if (InvalidServiceUrl(IdpSingleLogoutServiceUrl)) { yield return(new ValidationResult(i18nService.GetLocalizedHtmlString("IdpSingleLogoutServiceUrlInvalid"), new[] { nameof(IdpSingleLogoutServiceUrl) })); } if (!string.IsNullOrWhiteSpace(IdpX509PublicCert)) { // Validate the certificate is in a valid format ValidationResult failedResult = null; try { var certData = CoreHelpers.Base64UrlDecode(StripPemCertificateElements(IdpX509PublicCert)); new X509Certificate2(certData); } catch (FormatException) { failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertInvalidFormatValidationError"), new[] { nameof(IdpX509PublicCert) }); } catch (CryptographicException cryptoEx) { failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertCryptographicExceptionValidationError", cryptoEx.Message), new[] { nameof(IdpX509PublicCert) }); } catch (Exception ex) { failedResult = new ValidationResult(i18nService.GetLocalizedHtmlString("IdpX509PublicCertValidationError", ex.Message), new[] { nameof(IdpX509PublicCert) }); } if (failedResult != null) { yield return(failedResult); } } } }