public AuthController(IMapper mapper, UserManager <User> userManager, RoleManager <IdentityRole> roleManager, SignInManager <User> signInManager, IContext context, IOptionsSnapshot <JWTSetting> options) : base(mapper) { this.userManager = userManager; this.roleManager = roleManager; this.signInManager = signInManager; this.context = context; this.jwtOptions = options.Value; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); string privilegeDatabase = Configuration.GetConnectionString(MigrationManager.PRIVILEGE_CONNECTION_NAME).Replace("|DataDirectory|", System.IO.Directory.GetCurrentDirectory() + MigrationManager.DATABASE_PATH); services.AddDbContext <PrivilegeManagementContext>(options => options.UseSqlServer(privilegeDatabase)); string systemDatabase = Configuration.GetConnectionString(MigrationManager.SYSTEM_CONNECTION_NAME).Replace("|DataDirectory|", System.IO.Directory.GetCurrentDirectory() + MigrationManager.DATABASE_PATH); services.AddDbContext <SystemInfoContext>(option => option.UseSqlServer(systemDatabase)); services.AddTransient <IPrivilegeService, EFPrivilegeService>(); services.AddTransient <ISystemInfoService, SystemInfoService>(); services.AddAutoMapper(typeof(PrivilegeAutoMapperProfileConfiguration)); services.AddAutoMapper(typeof(SystemInfoAutoMapperProfileConfiguration)); services.Configure <JWTSetting>(Configuration.GetSection("JWTSetting")); JWTSetting jwtSetting = new JWTSetting(); Configuration.Bind("JWTSetting", jwtSetting); JWTHelper.Setting = jwtSetting; services.AddAuthentication(option => { option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(config => { config.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, //是否验证Issuer ValidateAudience = true, //是否验证Audience ValidateLifetime = true, //是否验证失效时间 ValidateIssuerSigningKey = true, //是否验证SecurityKey ValidAudience = jwtSetting.Audience, //Audience ValidIssuer = jwtSetting.Issuer, //Issuer,这两项和前面签发jwt的设置一致 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.SecretKey)), //拿到SecurityKey //ClockSkew = TimeSpan.FromSeconds(3)//缓冲过期时间,总的有效时间等于这个时间加上jwt的过期时间,如果不配置,默认是5分钟 }; }); }
/// <summary> /// 构造函数 /// </summary> /// <param name="Setting"></param> public LoginController(IOptions <JWTSetting> Setting) { _JWTsetting = Setting.Value; }
public AuthenticationController(IAuthenticationService authService, IOptions <JWTSetting> jwtSetting) { _authService = authService; _jwtSetting = jwtSetting.Value; }
public TokenController(JWTSetting jwtSetting) { _jwtSetting = jwtSetting; }
/// <summary> /// 注册JWT Bearer认证服务的静态扩展方法 /// </summary> /// <param name="services"></param> /// <param name="appSettings">JWT授权的配置项</param> public static void AddJwtBearerAuthentication(this IServiceCollection services, JWTSetting jwtSetting) { //使用应用密钥得到一个加密密钥字节数组 var key = Encoding.ASCII.GetBytes(jwtSetting.Secret); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddCookie(cfg => cfg.SlidingExpiration = true) .AddJwtBearer(x => { x.RequireHttpsMetadata = true; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = false, ValidateAudience = false }; x.Events = new JwtBearerEvents { //此处为权限验证失败后触发的事件 OnChallenge = context => { //此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要哦,必须 context.HandleResponse(); //自定义自己想要返回的数据结果,我这里要返回的是Json对象,通过引用Newtonsoft.Json库进行转换 var result = new ResponseResultBase(); result.SetFailed("很抱歉,您无权访问该接口", ErrorCode.NoPermission); var serializerSettings = new JsonSerializerSettings { // 设置为驼峰命名 ContractResolver = new CamelCasePropertyNamesContractResolver() }; var payload = JsonConvert.SerializeObject(result, serializerSettings); //自定义返回的数据类型 context.Response.ContentType = "application/json"; //自定义返回状态码,默认为401 我这里改成 200 context.Response.StatusCode = StatusCodes.Status200OK; //输出Json数据结果 context.Response.WriteAsync(payload); return(Task.FromResult(0)); } }; }); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddNewtonsoftJson(); JWTSetting jwtSetting = new JWTSetting { //Secret = Encoding.ASCII.GetBytes(Configuration.GetSection("JWT:Secret").Value) Secret = Encoding.ASCII.GetBytes(Configuration["JWT:Secret"]) }; services.AddSingleton(jwtSetting); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(x => { x.RequireHttpsMetadata = false; //x.SaveToken = true; x.SaveToken = false; //unicon7 : 일단 Identity가 없으므로! x.TokenValidationParameters = new TokenValidationParameters //TokenValidationParameters는 어떻게 token을 validate해야하는지 기술하는 중요 옵션, services에 따로 등록하는것을 추천! { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(jwtSetting.Secret), ValidateIssuer = false, //ValidIssuer = "The name of the issuer", ValidateAudience = false, //ValidAudience = "The name of the audience", ValidateLifetime = true, //ClockSkew = TimeSpan.FromMinutes(5) //5 minute tolerance for the expiration date }; //https://www.blinkingcaret.com/2018/05/30/refresh-tokens-in-asp-net-core-web-api/ //401만으로도 클라이인트가 처리 가능하다. Token-Expired: true를 추가로 더 쓰자. 클라이언트는 token을 refresh해야한다. x.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { if (context.Exception.GetType() == typeof(SecurityTokenExpiredException)) { context.Response.Headers.Add("Token-Expired", "true"); } return(Task.CompletedTask); } }; }); services.AddDbContextPool <AuthIdentityDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Local"))); services.AddIdentity <AuthIdentityUser, IdentityRole>().AddEntityFrameworkStores <AuthIdentityDbContext>(); services.AddApiVersioning( options => { // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions" //options.ReportApiVersions = true; }); services.AddVersionedApiExplorer( options => { // add the versioned api expl orer, which also adds IApiVersionDescriptionProvider service // note: the specified format code will format the version as "'v'major[.minor][-status]" options.GroupNameFormat = "'v'VVV"; // note: this option is only necessary when versioning by url segment. the SubstitutionFormat // can also be used to control the format of the API version in route templates options.SubstituteApiVersionInUrl = true; }); services.AddTransient <IConfigureOptions <SwaggerGenOptions>, ConfigureSwaggerOptions>(); services.AddSwaggerGen( options => { // add a custom operation filter which sets default values options.OperationFilter <SwaggerDefaultValues>(); var securityScheme = new OpenApiSecurityScheme { Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", Name = "Authorization", In = ParameterLocation.Header, Type = SecuritySchemeType.ApiKey, BearerFormat = "JWT", Scheme = "bearer" }; options.AddSecurityDefinition("Bearer", securityScheme); options.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] { } } }); // integrate xml comments options.IncludeXmlComments(XmlCommentsFilePath); }); }