public string Protect(AuthenticationTicket data) { if (data == null) { throw new ArgumentNullException(nameof(data)); } string audienceId = data.Properties.Dictionary.ContainsKey(AudiencePropertyKey) ? data.Properties.Dictionary[AudiencePropertyKey] : null; if (string.IsNullOrWhiteSpace(audienceId)) { throw new InvalidOperationException("AuthenticationTicket.Properties does not include audience"); } JwtAudience audience = (new AudiencesStore()).FindAudience(audienceId); string symmetricKeyAsBase64 = audience.Base64Secret; var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64); //var signingKey = new HmacSigningCredentials(keyByteArray); var signingKey = new SigningCredentials(new InMemorySymmetricSecurityKey(keyByteArray), SecurityAlgorithms.HmacSha256Signature, SecurityAlgorithms.Sha256Digest); var issued = data.Properties.IssuedUtc; var expires = data.Properties.ExpiresUtc; var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey); var handler = new JwtSecurityTokenHandler(); var jwt = handler.WriteToken(token); return(jwt); }
/// <summary> /// Get proper access rights mask depending on audience and user settings /// </summary> public static long?ResolveAccessRightsMask(IServiceProvider services, JwtAudience audience, User user) { var environment = services.GetRequiredService <IHostingEnvironment>(); var rights = (long)user.AccessRights; var defaultUserMaxRights = 0L | (long)AccessRights.Client; if (audience == JwtAudience.Cabinet) { // max rights are default user rights return(user.AccessRights & defaultUserMaxRights); } else if (audience == JwtAudience.Dashboard) { // tfa must be enabled if (!user.TwoFactorEnabled) { return(null); } // exclude client rights rights = (rights - defaultUserMaxRights); // has any of dashboard access rights - ok if (rights > 0) { return(rights); } } return(null); }
public string MakeAppLink(JwtAudience audience, string fragment) { var appUri = (string)null; if (audience == JwtAudience.Cabinet) { appUri = AppConfig.Apps.Cabinet.Url; } else if (audience == JwtAudience.Dashboard) { appUri = AppConfig.Apps.Dashboard.Url; } else { throw new NotImplementedException("Audience is not implemented. Could not create app link"); } var uri = new UriBuilder(new Uri(appUri)); if (fragment != null) { uri.Fragment = fragment; } return(uri.ToString()); }
public async Task <APIResponse> DebugAuth(long id, string audi) { var user = await UserManager.FindByIdAsync(id.ToString()); JwtAudience audience = JwtAudience.Cabinet; if (!string.IsNullOrWhiteSpace(audi)) { if (Enum.TryParse(audi, true, out JwtAudience aud)) { audience = aud; } } // denied var accessRightsMask = Core.UserAccount.ResolveAccessRightsMask(HttpContext.RequestServices, audience, user); if (accessRightsMask == null) { return(null); } return(APIResponse.Success( new AuthenticateView() { Token = JWT.CreateAuthToken( appConfig: AppConfig, user: user, audience: audience, area: JwtArea.Authorized, rightsMask: accessRightsMask.Value ), TfaRequired = false, })); }
/// <summary> /// Randomize access stamp /// </summary> public static void GenerateJwtSalt(User user, JwtAudience audience) { switch (audience) { case JwtAudience.Cabinet: user.JwtSaltCabinet = GenerateJwtSalt(); break; default: throw new NotImplementedException("Audience is not implemented"); } }
public IHttpActionResult AddAudience(JwtAudienceDto dto) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } JwtAudience newAudience = audiencesStore.AddAudience(dto.Name); return(Ok(newAudience)); }
/// <summary> /// Current access stamp /// </summary> public static string CurrentJwtSalt(User user, JwtAudience audience) { if (user == null) { return(null); } switch (audience) { case JwtAudience.Cabinet: return(user.JwtSaltCabinet); default: throw new NotImplementedException("Audience is not implemented"); } }
public void SaveConfiguration() { Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings[nameof(Configured)].Value = Configured.ToString(); config.AppSettings.Settings[nameof(ConnectionString)].Value = ConnectionString.ToString(); config.AppSettings.Settings[nameof(JwtIssuer)].Value = JwtIssuer.ToString(); config.AppSettings.Settings[nameof(JwtAudience)].Value = JwtAudience.ToString(); config.AppSettings.Settings[nameof(JwtExpiryInDays)].Value = JwtExpiryInDays.ToString(); config.AppSettings.Settings[nameof(JwtSecurityKey)].Value = JwtSecurityKey.ToString(); //config.AppSettings.Settings[nameof(ExtendsClassApi)].Value = ExtendsClassApi.ToString(); config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name); }
public override int GetHashCode() { int hash = 1; if (Selector.Length != 0) { hash ^= Selector.GetHashCode(); } if (Address.Length != 0) { hash ^= Address.GetHashCode(); } if (Deadline != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Deadline); } if (MinDeadline != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(MinDeadline); } if (OperationDeadline != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(OperationDeadline); } if (PathTranslation != global::Google.Api.BackendRule.Types.PathTranslation.Unspecified) { hash ^= PathTranslation.GetHashCode(); } if (authenticationCase_ == AuthenticationOneofCase.JwtAudience) { hash ^= JwtAudience.GetHashCode(); } if (authenticationCase_ == AuthenticationOneofCase.DisableAuth) { hash ^= DisableAuth.GetHashCode(); } if (Protocol.Length != 0) { hash ^= Protocol.GetHashCode(); } hash ^= (int)authenticationCase_; if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }
public JwtAudience AddAudience(string name) { var clientId = Guid.NewGuid().ToString("N"); var key = new byte[32]; RandomNumberGenerator.Create().GetBytes(key); var base64Secret = TextEncodings.Base64Url.Encode(key); var audience = new JwtAudience { ClientId = clientId, Base64Secret = base64Secret, Name = name }; _context.JwtAudiences.Add(audience); _context.SaveChanges(); return(audience); }
// --- /// <summary> /// Make a token for specified user with specified state /// </summary> public static string CreateAuthToken(AppConfig appConfig, JwtAudience audience, JwtArea area, User user, long rightsMask) { var now = DateTime.UtcNow; var uniqueness = UniqueId(appConfig.Auth.Jwt.Secret); var audienceSett = GetAudienceSettings(appConfig, audience); var jwtSalt = UserAccount.CurrentJwtSalt(user, audience); var claims = new[] { // jw main fields new Claim(JwtRegisteredClaimNames.Sub, uniqueness), new Claim(JwtRegisteredClaimNames.Jti, uniqueness), new Claim(JwtRegisteredClaimNames.Iat, ((DateTimeOffset)now).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64), // gm fields new Claim(ErSecurityStampField, ObtainSecurityStamp(jwtSalt)), new Claim(ErIdField, user.UserName), new Claim(ErRightsField, rightsMask.ToString()), new Claim(ErAreaField, area.ToString().ToLower()), }; var claimIdentity = new ClaimsIdentity( claims, JwtBearerDefaults.AuthenticationScheme ); var creds = new SigningCredentials( CreateJwtSecurityKey(appConfig.Auth.Jwt.Secret), SecurityAlgorithms.HmacSha256 ); var token = new JwtSecurityToken( issuer: appConfig.Auth.Jwt.Issuer, audience: audienceSett.Audience.ToLower(), claims: claimIdentity.Claims, signingCredentials: creds, expires: now.AddSeconds(audienceSett.ExpirationSec) ); return((new JwtSecurityTokenHandler()).WriteToken(token)); }
public override int GetHashCode() { int hash = 1; if (Selector.Length != 0) { hash ^= Selector.GetHashCode(); } if (Address.Length != 0) { hash ^= Address.GetHashCode(); } if (Deadline != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(Deadline); } if (MinDeadline != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(MinDeadline); } if (OperationDeadline != 0D) { hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(OperationDeadline); } if (PathTranslation != 0) { hash ^= PathTranslation.GetHashCode(); } if (authenticationCase_ == AuthenticationOneofCase.JwtAudience) { hash ^= JwtAudience.GetHashCode(); } hash ^= (int)authenticationCase_; if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }
/// <summary> /// Make a security token /// </summary> public static string CreateSecurityToken(AppConfig appConfig, JwtAudience audience, JwtArea area, string entityId, string securityStamp, TimeSpan validFor, IEnumerable <Claim> optClaims = null) { var now = DateTime.UtcNow; var uniqueness = UniqueId(appConfig.Auth.Jwt.Secret); var audienceSett = GetAudienceSettings(appConfig, audience); var claims = new List <Claim>() { // jw main fields new Claim(JwtRegisteredClaimNames.Sub, uniqueness), new Claim(JwtRegisteredClaimNames.Jti, uniqueness), new Claim(JwtRegisteredClaimNames.Iat, ((DateTimeOffset)now).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64), // gm fields new Claim(ErIdField, entityId), new Claim(ErSecurityStampField, ObtainSecurityStamp(securityStamp)), new Claim(ErAreaField, area.ToString().ToLower()), }; if (optClaims != null) { claims.AddRange(optClaims); } var creds = new SigningCredentials( CreateJwtSecurityKey(appConfig.Auth.Jwt.Secret), SecurityAlgorithms.HmacSha256 ); var token = new JwtSecurityToken( issuer: appConfig.Auth.Jwt.Issuer, audience: audienceSett.Audience.ToLower(), claims: claims, signingCredentials: creds, expires: now.Add(validFor) ); return((new JwtSecurityTokenHandler()).WriteToken(token)); }
public string MakeAppLink(JwtAudience audience, string fragment = null) { var origin = ""; if (HttpContext.Request?.Headers?.TryGetValue("Origin", out var val) ?? false) { origin = val.ToString(); } var appUri = ""; if (audience == JwtAudience.Cabinet) { appUri = AppConfig.Apps.Cabinet.Url.FirstOrDefault(); foreach (var u in AppConfig.Apps.Cabinet.Url) { if (u.IndexOf(origin) == 0) { appUri = u; break; } } } else { throw new NotImplementedException("Audience is not implemented. Could not create app link"); } var uri = new UriBuilder(new Uri(appUri)); if (!string.IsNullOrWhiteSpace(fragment)) { uri.Fragment = fragment; } return(uri.ToString()); }
public async Task <APIResponse> Authenticate([FromBody] AuthenticateModel model) { var notFoundDesc = "Account not found"; // validate if (BaseValidableModel.IsInvalid(model, out var errFields)) { return(APIResponse.BadRequest(APIErrorCode.AccountNotFound, notFoundDesc)); } var agent = GetUserAgentInfo(); var userLocale = GetUserLocale(); var user = await UserManager.FindByNameAsync(model.Username) ?? await UserManager.FindByEmailAsync(model.Username); if (user != null) { bool isLockedOut = false; // locked out if (user.LockoutEnd != null && user.LockoutEnd.Value.UtcDateTime > DateTime.UtcNow) { // unlock before this check isLockedOut = true; user.LockoutEnd = null; } // get audience JwtAudience audience = JwtAudience.Cabinet; if (!string.IsNullOrWhiteSpace(model.Audience)) { if (Enum.TryParse(model.Audience, true, out JwtAudience aud)) { audience = aud; } } // load options await DbContext.Entry(user).Reference(_ => _.UserOptions).LoadAsync(); var sres = OnSignInResultCheck( services: HttpContext.RequestServices, result: await SignInManager.CheckPasswordSignInAsync(user, model.Password, lockoutOnFailure: true), audience: audience, user: user, tfaRequired: user.TwoFactorEnabled ); if (sres != null) { // successful result if (sres.GetHttpStatusCode() == System.Net.HttpStatusCode.OK && sres.GetErrorCode() == null) { // notification await EmailComposer.FromTemplate(await TemplateProvider.GetEmailTemplate(EmailTemplate.SignedIn, userLocale)) .ReplaceBodyTag("IP", agent.Ip) .Initiator(agent.Ip, agent.Agent, DateTime.UtcNow) .Send(user.Email, user.UserName, EmailQueue) ; // activity var userActivity = CoreLogic.User.CreateUserActivity( user: user, type: Common.UserActivityType.Auth, comment: "Signed in with password", ip: agent.Ip, agent: agent.Agent, locale: userLocale ); DbContext.UserActivity.Add(userActivity); await DbContext.SaveChangesAsync(); } return(sres); } // was locked before if (isLockedOut) { await UserManager.SetLockoutEndDateAsync(user, (DateTimeOffset)DateTime.UtcNow.AddMinutes(60)); return(APIResponse.BadRequest(APIErrorCode.AccountLocked, "Too many unsuccessful attempts. Account is locked, try to sign in later")); } } return(APIResponse.BadRequest(APIErrorCode.AccountNotFound, notFoundDesc)); }
/// <summary> /// Audience settings /// </summary> private static AppConfig.AuthSection.JwtSection.AudienceSection GetAudienceSettings(AppConfig appConfig, JwtAudience audience) { return((from a in appConfig.Auth.Jwt.Audiences where a.Audience == audience.ToString() select a).FirstOrDefault()); }
private APIResponse OnSignInResultCheck(IServiceProvider services, SignInResult result, DAL.Models.Identity.User user, JwtAudience audience, bool tfaRequired) { if (result != null) { if (result.Succeeded || result.RequiresTwoFactor) { // denied var accessRightsMask = Core.UserAccount.ResolveAccessRightsMask(services, audience, user); if (accessRightsMask == null) { return(null); } // tfa token if (tfaRequired || result.RequiresTwoFactor) { return(APIResponse.Success( new AuthenticateView() { Token = JWT.CreateAuthToken( appConfig: AppConfig, user: user, audience: audience, area: JwtArea.Tfa, rightsMask: accessRightsMask.Value ), TfaRequired = true, } )); } // new jwt salt UserAccount.GenerateJwtSalt(user, audience); DbContext.SaveChanges(); // auth token return(APIResponse.Success( new AuthenticateView() { Token = JWT.CreateAuthToken( appConfig: AppConfig, user: user, audience: audience, area: JwtArea.Authorized, rightsMask: accessRightsMask.Value ), TfaRequired = false, } )); } if (result.IsLockedOut) { return(APIResponse.BadRequest(APIErrorCode.AccountLocked, "Too many unsuccessful attempts to sign in. Account is locked, try to sign in later")); } if (result.IsNotAllowed) { return(APIResponse.BadRequest(APIErrorCode.AccountEmailNotConfirmed, "Email is not confirmed yet")); } } // not found return(null); }
public RequireJWTAudience(JwtAudience audience) { _audience = audience; }