public string GenerateToken(ContextUserDTO user, double?minutesExpiration = null) { try { TokenConfigurationsDTO _tokenConfigurations = _configuration.GetSection("TokenConfigurations") ?.Get <TokenConfigurationsDTO>(); if (_tokenConfigurations == null) { throw new ArgumentNullException("Não foi possível encontrar as configurações do Token JWT."); } JwtSecurityTokenHandler _tokenHandler = new JwtSecurityTokenHandler(); byte[] _key = Encoding.ASCII.GetBytes(_tokenConfigurations.Secret); SecurityTokenDescriptor _tokenDescriptor = new SecurityTokenDescriptor { Subject = _serviceAuth.GetClaimsIdentityByContextUser(user), Expires = DateTime.UtcNow.AddMinutes(minutesExpiration ?? _tokenConfigurations.ExpiresIn), NotBefore = DateTime.UtcNow, SigningCredentials = new SigningCredentials( new SymmetricSecurityKey(_key), SecurityAlgorithms.HmacSha256Signature) }; SecurityToken _generatedToken = _tokenHandler.CreateToken(_tokenDescriptor); return(_tokenHandler.WriteToken(_generatedToken)); } catch (Exception) { throw; } }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddTransient <UsuariosDAO>(); services.AddTransient <TreinosDAO>(); services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Version = "v1", Title = "Treino API", Description = "" }); }); string conn = @"Data Source=Lucas-PC;Initial Catalog=Treino;User ID=USR_Treino;Password=081991@RAtm"; services.AddDistributedSqlServerCache(opt => { opt.ConnectionString = conn; opt.SchemaName = "dbo"; opt.TableName = "SQLCache"; }); var signingConfigurations = new SigningConfigurationsDTO(); services.AddSingleton(signingConfigurations); var tokenConfigurations = new TokenConfigurationsDTO(); new ConfigureFromConfigurationOptions <TokenConfigurationsDTO>( Configuration.GetSection("TokenConfigurations")) .Configure(tokenConfigurations); services.AddSingleton(tokenConfigurations); services.AddAuthentication(authOptions => { authOptions.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; authOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(bearerOptions => { var paramsValidation = bearerOptions.TokenValidationParameters; paramsValidation.IssuerSigningKey = signingConfigurations.Key; paramsValidation.ValidAudience = tokenConfigurations.Audience; paramsValidation.ValidIssuer = tokenConfigurations.Issuer; // Valida a assinatura de um token recebido paramsValidation.ValidateIssuerSigningKey = true; // Verifica se um token recebido ainda é válido paramsValidation.ValidateLifetime = true; // Tempo de tolerância para a expiração de um token (utilizado // caso haja problemas de sincronismo de horário entre diferentes // computadores envolvidos no processo de comunicação) paramsValidation.ClockSkew = TimeSpan.Zero; }); // Ativa o uso do token como forma de autorizar o acesso // a recursos deste projeto services.AddAuthorization(auth => { auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder() .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme) .RequireAuthenticatedUser().Build()); }); services.AddCors(options => { options.AddPolicy(MyAllowSpecificOrigins, builder => { builder.WithOrigins("*") .AllowAnyHeader() .AllowAnyMethod(); }); }); services.Configure <MvcOptions>(options => { options.Filters.Add(new CorsAuthorizationFilterFactory("AllowOthersOrigins")); }); services.AddMvc(config => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); config.Filters.Add(new AuthorizeFilter(policy)); }); services.AddMvc(); }
public IActionResult PostLogin([FromBody] LoginDTO login, [FromServices] UsuariosDAO usuariosDAO, [FromServices] SigningConfigurationsDTO signingConfigurations, [FromServices] TokenConfigurationsDTO tokenConfigurations, [FromServices] IDistributedCache cache) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } bool credenciaisValidas = false; var _IDUsuario = string.Empty; AccessDataDTO _accessData = new AccessDataDTO(); try { if (login.Grant_Type == "password") { var _usuario = usuariosDAO.SelectUsuarioPorCredenciais(login.Email, login.Password); credenciaisValidas = (_usuario != null); if (credenciaisValidas) { if (_usuario.Ativo == false) { return(BadRequest("Usuário bloqueado! Entre em contato com o administrador.")); } _IDUsuario = _usuario.IDUsuario.ToString(); } } else if (login.Grant_Type == "refresh_token") { RefreshTokenDataDTO refreshTokenBase = null; string strTokenArmazenado = cache.GetString(login.RefreshToken); if (!String.IsNullOrWhiteSpace(strTokenArmazenado)) { refreshTokenBase = JsonConvert.DeserializeObject <RefreshTokenDataDTO>(strTokenArmazenado); } credenciaisValidas = (refreshTokenBase != null && login.RefreshToken == refreshTokenBase.RefreshToken); // Elimina o token de refresh já que um novo será gerado if (credenciaisValidas) { _IDUsuario = refreshTokenBase.IDUsuario; cache.Remove(login.RefreshToken); } } else { return(BadRequest("Invalid grant_type")); } if (!credenciaisValidas) { return(BadRequest("Usuário ou senha inválidos. Caso não se lembre, clique em esqueci minha senha!")); } _accessData = GenerateToken(_IDUsuario, signingConfigurations, tokenConfigurations, cache); SaveSessao(_IDUsuario, login, _accessData); } catch (Exception ex) { return(BadRequest(ex)); } return(Ok(_accessData)); }
public static IServiceCollection AddCustomJWTConfiguration(this IServiceCollection services, IConfiguration configuration) { try { TokenConfigurationsDTO _tokenConfigurations = configuration.GetSection("TokenConfigurations") ?.Get <TokenConfigurationsDTO>(); if (_tokenConfigurations == null) { throw new ArgumentNullException("Não foi possível encontrar as configurações do Token JWT."); } byte[] _key = Encoding.ASCII.GetBytes(_tokenConfigurations.Secret); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(_key), ValidateIssuer = false, //caso o servidor de autorização seja diferente ValidateAudience = false, //seria o servidor que vai fazer o request da autorização pro Issuer RequireExpirationTime = true }; x.Events = new JwtBearerEvents { OnMessageReceived = context => { context.Request.Headers.TryGetValue("Authorization", out StringValues accessToken); string _path = context.HttpContext.Request.Path.ToString(); if (!string.IsNullOrEmpty(accessToken) && _path.Contains("/notificacoes-logged-user")) { if (accessToken.ToString().Contains("Bearer")) { accessToken = accessToken.ToString().Split(' ')[1]; } context.Token = accessToken; } return(Task.CompletedTask); } }; }); return(services); } catch (Exception) { throw; } }
private AccessDataDTO GenerateToken(string userID, SigningConfigurationsDTO signingConfigurations, TokenConfigurationsDTO tokenConfigurations, IDistributedCache cache) { ClaimsIdentity identity = new ClaimsIdentity( new GenericIdentity(userID, "IDUsuario"), new[] { new Claim("IDUsuario", userID) } ); DateTime dataCriacao = DateTime.Now; DateTime dataExpiracao = dataCriacao + TimeSpan.FromSeconds(tokenConfigurations.Seconds); // Calcula o tempo máximo de validade do refresh token // (o mesmo será invalidado automaticamente pelo Redis) TimeSpan finalExpiration = TimeSpan.FromSeconds(tokenConfigurations.FinalExpiration); var handler = new JwtSecurityTokenHandler(); var securityToken = handler.CreateToken(new SecurityTokenDescriptor { Issuer = tokenConfigurations.Issuer, Audience = tokenConfigurations.Audience, SigningCredentials = signingConfigurations.SigningCredentials, Subject = identity, NotBefore = dataCriacao, Expires = dataExpiracao }); var token = handler.WriteToken(securityToken); AccessDataDTO resultado = new AccessDataDTO(); resultado.AccessToken = token; resultado.RefreshToken = Guid.NewGuid().ToString().Replace("-", String.Empty); resultado.Created = dataCriacao.ToString("yyyy-MM-dd HH:mm:ss"); resultado.Expiration = dataExpiracao.ToString("yyyy-MM-dd HH:mm:ss"); // Armazena o refresh token em cache através do Redis var refreshTokenData = new RefreshTokenDataDTO(); refreshTokenData.RefreshToken = resultado.RefreshToken; refreshTokenData.IDUsuario = userID; DistributedCacheEntryOptions opcoesCache = new DistributedCacheEntryOptions(); opcoesCache.SetAbsoluteExpiration(finalExpiration); cache.SetString(resultado.RefreshToken, JsonConvert.SerializeObject(refreshTokenData), opcoesCache); return(resultado); }