[英]ASP.NET Core 2.1, Angular 5: Hangfire Auth only works on login
I have an ASP.NET Core 2.1 Web API that uses an Angular 5 front-end. 我有一个使用Angular 5前端的ASP.NET Core 2.1 Web API。 When I call the
Login()
method, it saves a Cookie to the session. 当我调用
Login()
方法时,它将Cookie保存到会话中。
Response.Cookies.Append("UserRole", userFromRepo.UserRole.ToString());
Then when accessing the Hangfire dashboard, I check for that cookie, and authorize if the user is an Admin (See Startup.cs below). 然后在访问Hangfire仪表板时,我检查该cookie,并授权该用户是否为管理员(请参见下面的Startup.cs)。
However, since I am using JWT tokens, and the front-end token doesn't expire right away, if the user closes the browser and re-opens my site, they don't have to log in, but it is a new session, so the cookie no longer exists. 但是,由于我正在使用JWT令牌,并且前端令牌不会立即过期,因此如果用户关闭浏览器并重新打开我的网站,则不必登录,但这是一个新会话,因此Cookie不再存在。
Is there a more persistent way to store the user's role? 有没有更持久的方法来存储用户的角色? (no, I'm not using Identity) Or is there a way to re-instantiate the cookie at the startup of the new session?
(不,我没有使用Identity)还是有办法在新会话启动时重新实例化cookie?
AuthController.cs AuthController.cs
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] UserForLoginDto userForLoginDto)
{
var userFromRepo = await _repo.Login(userForLoginDto.Username.ToLower(), userForLoginDto.Password);
//stuff to generate tokenString
Response.Cookies.Append("UserRole", userFromRepo.UserRole.ToString());
return Ok(new { tokenString, user });
}
Startup.cs Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddHangfire(config =>
config.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc()
.AddJsonOptions(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<IAuthRepository, AuthRepository>();
services.AddScoped<IBaseRepository, BaseRepository>();
services.AddSingleton(Configuration);
var key = Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler(builder =>
{
builder.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
context.Response.AddApplicationError(error.Error.Message);
await context.Response.WriteAsync(error.Error.Message);
}
});
});
}
app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseHangfireDashboard("/hangfire", new DashboardOptions()
{
Authorization = new[] {new HangfireAuthorizationFilter()}
});
app.UseHangfireServer();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
}
});
}
}
public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize([NotNull] DashboardContext context)
{
try
{
var httpContext = context.GetHttpContext();
var userRole = httpContext.Request.Cookies["UserRole"];
return userRole == UserRole.Admin.ToString();
}
catch
{
return false;
}
}
}
AuthController.cs AuthController.cs
Ok, a couple months later, I came back to this... here's how I got it to work! 好的,几个月后,我又回到了...这是我如何使其工作的方法!
AddCookie()
to save the value within request's cookies (within ConfigureServices
) AddCookie()
将值保存在请求的Cookie中(在ConfigureServices
) HangfireAuthorizationFilter
that searches for the UserRole cookie and compares it to my UserRoles enum. HangfireAuthorizationFilter
来搜索UserRole cookie,并将其与我的UserRoles枚举进行比较。 Configure
) Configure
) public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(x => x
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
b =>
{
b.MigrationsAssembly(("MyApp"));
b.EnableRetryOnFailure();
})
.ConfigureWarnings(warnings => warnings.Ignore(CoreEventId.IncludeIgnoredWarning)));
services.AddMvc()
.AddJsonOptions(opt =>
{
opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Events = new JwtBearerEvents
{
OnTokenValidated = async ctx =>
{
var clientId = ctx.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var db = ctx.HttpContext.RequestServices.GetRequiredService<DataContext>();
var user = await db.Users.FirstOrDefaultAsync(u => u.Id == int.Parse(clientId));
if (user != null)
{
var userRole = user.UserRole;
var claims = new List<Claim>
{
new Claim(ClaimTypes.Role, userRole.ToString())
};
var appIdentity = new ClaimsIdentity(claims);
ctx.Principal.AddIdentity(appIdentity);
}
}
};
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
}).AddCookie();
//...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseAuthentication();
app.UseHangfireDashboard("/hangfire", new DashboardOptions()
{
Authorization = new[] { new HangfireAuthorizationFilter() }
});
app.UseHangfireServer();
//...
}
}
public class HangfireAuthorizationFilter : ControllerBase, IDashboardAuthorizationFilter
{
public bool Authorize([NotNull] DashboardContext context)
{
try
{
var httpContext = context.GetHttpContext();
var userRole = httpContext.Request.Cookies["UserRole"];
return userRole == UserRole.Admin.ToString();
}
catch
{
return false;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.