using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using Syski.API.Services; using Syski.Data; using System; using System.IdentityModel.Tokens.Jwt; using System.Text; namespace csharp.api { public class Startup { public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); // Make all the urls lowercase as this is good web practice services.AddRouting(options => options.LowercaseUrls = true); // Load the connection string from the settings file and use it for storing data services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")) ); // Add Identity to the application services.AddDefaultIdentity() .AddEntityFrameworkStores(); // Java Web Tokens Authentication JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, cfg => { cfg.RequireHttpsMetadata = true; cfg.SaveToken = true; cfg.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])), ValidateIssuer = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidateAudience = true, ValidAudience = Configuration["Jwt:Audience"], ValidateLifetime = true, ClockSkew = TimeSpan.Zero //ClockSkew = TimeSpan.FromMinutes(5) }; }) .AddJwtBearer("refresh", cfg => { cfg.RequireHttpsMetadata = true; cfg.SaveToken = true; cfg.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])), ValidateIssuer = true, ValidIssuer = Configuration["Jwt:Issuer"], ValidateAudience = true, ValidAudience = Configuration["Jwt:Audience"], ValidateLifetime = false, ClockSkew = TimeSpan.Zero //ClockSkew = TimeSpan.FromMinutes(5) }; }); services.AddAuthorization(options => { options.AddPolicy("refreshtoken", new AuthorizationPolicyBuilder().RequireAuthenticatedUser().AddAuthenticationSchemes("refresh").Build()); }); services.AddTransient(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { app.UseHsts(); } try { if (Convert.ToBoolean(Configuration["ReverseProxy"])) { app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); } } catch { // Error parsing config, do nothing assume not behind a reverse proxy } app.UseHttpsRedirection(); app.UseAuthentication(); app.UseMvc(); } } }