Entity framework core 将ID传递给控制器一次,并让所有控制器方法记住布尔检查
我刚刚使用.netcore2.2和实体框架创建了一个简单的web API 通过向用户访问的每个控制器传递用户ID,我增加了一点安全性 但我注意到,当我必须将用户ID添加到我应用程序中的每个控制器并运行我的用户检查以确保用户可以访问该内容时,它开始变得混乱 下面你会看到一个例子,我的意思 我想知道,有没有办法添加一次,然后让每个控制器检查它 谢谢Entity framework core 将ID传递给控制器一次,并让所有控制器方法记住布尔检查,entity-framework-core,asp.net-core-2.0,asp.net-core-webapi,Entity Framework Core,Asp.net Core 2.0,Asp.net Core Webapi,我刚刚使用.netcore2.2和实体框架创建了一个简单的web API 通过向用户访问的每个控制器传递用户ID,我增加了一点安全性 但我注意到,当我必须将用户ID添加到我应用程序中的每个控制器并运行我的用户检查以确保用户可以访问该内容时,它开始变得混乱 下面你会看到一个例子,我的意思 我想知道,有没有办法添加一次,然后让每个控制器检查它 谢谢 [Route("api/[controller]")] [ApiController] public class EngineController :
[Route("api/[controller]")]
[ApiController]
public class EngineController : ControllerBase
{
private readonly engineMaker_Context _context;
public EngineController(engineMaker_Context context)
{
_context = context;
}
// GET: api/Engine
[HttpGet("{userID}")]
public async Task<ActionResult<IEnumerable<Engine>>> GetEngine(string userID)
{
if(!CanAccessContent(userID))
{
return Unauthorized();
}
return await _context.Engine.ToListAsync();
}
// GET: api/Engine/123/5
[HttpGet("{userID}/{id}")]
public async Task<ActionResult<Engine>> GetEngine(string userID, string id)
{
if(!CanAccessContent(userID))
{
return Unauthorized();
}
var engine = await _context.Engine.FindAsync(id);
if (engine == null)
{
return NotFound();
}
return engine;
}
// PUT: api/Engine/123/5
[HttpPut("{userID}/{id}")]
public async Task<IActionResult> PutEngine(string userID, string id, Engine engine)
{
if(!CanAccessContent(userID))
{
return Unauthorized();
}
if (id != engine.ObjectId)
{
return BadRequest();
}
_context.Entry(engine).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!EngineExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
private bool CanAccessContent(string userID)
{
return _context.AllowedUsers.Any(e => e.UserId == userID);
}
}
[路由(“api/[控制器]”)]
[ApiController]
公共类EngineController:ControllerBase
{
私有只读引擎制造商上下文;
公共EngineController(engineMaker\u上下文)
{
_上下文=上下文;
}
//获取:api/引擎
[HttpGet(“{userID}”)]
公共异步任务GetEngine(字符串用户ID)
{
if(!CanAccessContent(userID))
{
未经授权返回();
}
return wait_context.Engine.toListSync();
}
//获取:api/Engine/123/5
[HttpGet(“{userID}/{id}”)]
公共异步任务GetEngine(字符串用户id、字符串id)
{
if(!CanAccessContent(userID))
{
未经授权返回();
}
var engine=wait_context.engine.FindAsync(id);
如果(引擎==null)
{
返回NotFound();
}
返回引擎;
}
//PUT:api/Engine/123/5
[HttpPut(“{userID}/{id}”)]
公共异步任务引擎(字符串用户id、字符串id、引擎引擎)
{
if(!CanAccessContent(userID))
{
未经授权返回();
}
if(id!=engine.ObjectId)
{
返回请求();
}
_context.Entry(engine.State=EntityState.Modified;
尝试
{
wait_context.SaveChangesAsync();
}
catch(DbUpdateConcurrencyException)
{
如果(!EngineeExists(id))
{
返回NotFound();
}
其他的
{
投掷;
}
}
返回NoContent();
}
私有bool CanAccessContent(字符串userID)
{
返回_context.AllowedUsers.Any(e=>e.UserId==UserId);
}
}
您可以尝试IAsyncAuthorizationFilter
检查用户ID
IAsyncAuthorizationFilter
public class UserIdFilter : IAsyncAuthorizationFilter
{
public Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
var dbContext = context.HttpContext.RequestServices.GetRequiredService<ApplicationDbContext>();
var userId = context.RouteData.Values["userID"] as string;
if (!dbContext.Users.Any(u => u.Email == userId))
{
context.Result = new UnauthorizedResult();
}
return Task.CompletedTask;
}
}
谢谢这会出现在startup.cs文件或我的任何控制器中吗?@SkyeBoniwell您是否使用asp.net core进行开发?您应该在
Startup.cs
中使用services.AddMvc
。是的,我使用的是.NETCore2.2和EntityFramework。那么我就把你上面的那句话加到我的.AddMvc调用中?如何将acutal用户标识传递到该文件中?谢谢@你试过上面的代码吗?首先,你有错误吗?传递用户ID是什么意思?作为具有[HttpGet(“{userID}”)]
的当前控制器,您可以使用userID
作为路由数据传递请求。或者,您可以将userId
作为请求头传递,您可以在AuthorizationAsync(AuthorizationFilterContext context)上访问public任务中的请求
HI Tao,对不起,我说话不正确。我应该问,“userId”是如何从控制器传递到Startup.cs中的代码的。非常感谢。
services.AddMvc(options =>
{
options.Filters.Add(typeof(UserIdFilter));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);