如何设计控制器动作来响应猜测和授权用户
本文关键字:响应 用户 授权 控制器 | 更新日期: 2023-09-27 18:15:33
我在控制器设计中为已经在系统中注册的用户设置了一个动作:
[Authorize]
public ActionResult getUserData()
{
string UserId = User.Identity.GetUserId();
return getDataFromDB(UserID);
}
并且工作正常。如果您还没有通过身份验证,也可以重定向到LOGIN
页面。
但我也想有一个虚拟函数getFakeData()
匿名用户访问页面,这样他们就可以看到类似的页面演示。
我应该在哪里放置验证以查看用户是否经过身份验证并更改行为?
在网页上,我可以设置基于用户是否被认证的dataUrl。我可以做一个没有
[Authorize]
标签的分离函数@if (Request.IsAuthenticated) { dataUrl = '=/Project/Controller/getUserData' } else { dataUrl = '=/Project/Controller/getFakeData' }
或者我可以在相同的动作控制器上做,并检查用户是否经过身份验证?但我不确定这是否可能。
或者是更好的方法?
有多种方法可以做到这一点,但这里是我的建议
// For ASP.Net MVC 5 simply inherit from AuthorizationAttribute and override the methods.
public class AccessControlAttribute : Attribute, IAuthorizationFilter
{
private readonly Roles role;
public AccessControlAttribute(Roles role) {
this.role = role;
}
private Boolean AuthorizationCore(AuthorizationFilterContext context) {
var username = context.HttpContext.Request.Cookies["loginCookie_username"];
var password = context.HttpContext.Request.Cookies["loginCookie_password"];
if (role == Roles.FakeFullAccess) {
username = "FAKE";
goto final;
}
//In ASP.Net MVC 5 use Ninject for dependency injection and get the service using : [NinjectContext].GetKernel.Get<DbContext>();
DbContext db = (DbContext) context.HttpContext.RequestServices.GetService(typeof(DbContext));
if (username != null && password != null) {
var findUser = db.Set<Login>().Find(username);
if (findUser != null && findUser.Password.Equals(password) && findUser.RoleId == (int)role) {
goto final;
}
}
return false;
final: {
context.HttpContext.User.AddIdentity(new System.Security.Principal.GenericIdentity(username));
return true;
}
}
private void HandleUnauthorizedRequest(AuthorizationFilterContext context) {
context.Result = new RedirectToRouteResult(new {
area = "",
controller = "",
action = ""
});
}
public void OnAuthorization(AuthorizationFilterContext context)
{
if (AuthorizationCore(context))
{
// If using a combination of roles, you have to unmask it
if (role == Roles.FakeFullAccess) {
context.HttpContext.Request.Headers.Add("Render", "FakeAccess");
}
else if (role == Roles.Admin)
{
context.HttpContext.Request.Headers.Add("Render", "AdminAccess");
}
}
else {
HandleUnauthorizedRequest(context);
}
}
}
[Flags]
public enum Roles
{
FakeFullAccess = 0,
ReadOnly = 1,
Admin = 2,
Supervisor = 1 << 2,
AnotherRole = 1 << 3
}
在您的视图中,您可以读取添加的标题和自定义视图(在ASP。Net Core没有访问ControllerContext和ViewBag,如果使用ASP。. Net MVC 5你不需要使用头的技巧)
// For ASP.Net MVC 5 use the ViewBag or ViewData
@Html.Partial(HttpContext.Request.Header["Render"])
//Assuming this renders the menu with proper functions.
现在您拥有了完全可定制的基于角色的身份验证系统,并具有用于测试的假访问。
更新:要使用该属性,请执行以下操作
[AccessControl(Role.Admin)]
public TestController: Controller {
...
}
// Dedicated for testing
[AccessControl(Role.FakeAccess)]
public PreviewController: TestCoontroller{}
如果需要的话,你也可以像[AccessControl(Role.FakeAccess | Role.ReadOnly)]
那样组合角色,但是你必须实现一个揭开面具的方法。