如何将一个控制器的方法授权给一个角色或多个角色,而不会取消整个控制器。
如何将一个控制器的方法授权给一个角色或多个角色,而不会取消整个控制器。
我正试图通过角色限制访问我的控制器的方法,以传统的方式,完整的控制器拒绝了所有角色的用户的身份验证
这是一个带有多个角色的授权属性
using MBC.ServiciosUtilidad.CatalogoUS.Implementacion; using MBC.ServiciosEntidad.ReportesDmsES.Implementacion; using System.Web.Mvc; using MBC.Models.ReportDms; using PagedList; using System.Data; using System.Linq; using MBC.ModeloCanonico.Constantes; using System.Web.Security; using static MBC.ModeloCanonico.Constantes.CatalogoConstante; namespace MBC.Controllers.Report.Vehiculos { [Authorize] //[Authorize(Roles = CatalogoConstante.Rol.Administrador)] public class ReportDmsVehiculosController : MasterController { private readonly ICatalogoUSContract _servicioCatalogo; private readonly IReportesDmsESContrato _servicioReportesDms; //构造函数 public ReportDmsVehiculosController() { _servicioCatalogo = new CatalogoUSImplementacion(); _servicioReportesDms = new ReportesDmsESImplementacion(); } //[Authorize(Roles = CatalogoConstante.Rol.Administrador)] [AuthorizeRoles(Rol.Administrador)] public ActionResult ReportDmsVehiculos() { return View(); } } } namespace MBC.ModeloCanonico.Constantes { public static class CatalogoConstante { public struct Rol { public const string Administrador = "Administrador"; public const string RecursosHumanos = "Recursos Humanos"; } } }
这是一个带有返回消息“访问被拒绝”的登录()
public ActionResult Login() { //if (User.Identity.IsAuthenticated) if (User.IsInRole("ProvideASpecificRoleHere")) return RedirectToAction("Index", "Home"); if (User.Identity.IsAuthenticated) ModelState.AddModelError("", "访问被拒绝。"); return View(); }
由于某种原因,它一直把我送到:RedirectToAction("Index", "Home"),这只应该在开始时发生
[HttpPost] public ActionResult Login(LoginModel model) { if (User.Identity.IsAuthenticated) { return RedirectToAction("Index", "Home"); } UserRol userRol = new UserRol(); userRol.user = _serviceUsuario.ValidarCredencialesRol(model.Usuario, model.Contrasena); if (userRol.user != null) { model.Roles = userRol.user.Roles; FormsAuthentication.SetAuthCookie(model.Usuario, false); ((ClaimsIdentity)HttpContext.User.Identity).AddClaim(new Claim(ClaimTypes.Role, model.Roles)); var authTicket = new FormsAuthenticationTicket(1, model.Usuario, DateTime.Now, DateTime.Now.AddMinutes(20), false, model.Roles); string encryptedTicket = FormsAuthentication.Encrypt(authTicket); var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); HttpContext.Response.Cookies.Add(authCookie); return RedirectToAction("Index", "Home"); } else { ModelState.AddModelError("", "无效的登录尝试。"); return View(model); } } protected override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); UsuarioLogueado(); }
这是已注册用户的验证功能。这个类用于获取登录用户的信息,用于审计和在视图中显示一些数据。
protected void UsuarioLogueado() { try { if (User.Identity.IsAuthenticated) { var usuarioLogueado = Session["UsarioEntityModel"] as UsarioEntityModel; if (usuarioLogueado == null) { usuarioLogueado = _userService.ObtenerUsuarioLogueado(User.Identity.Name).ToUsarioEntityModel(); ((ClaimsIdentity)HttpContext.User.Identity).AddClaim(new Claim(ClaimTypes.Role, usuarioLogueado.Rol)); Session["UsarioEntityModel"] = usuarioLogueado; } ViewBag.usuarioLogueado = usuarioLogueado; } else { Session["UsarioEntityModel"] = null; } } catch (AggregateException ex) { throw ex; } }
问题的出现原因:
根据提供的代码,您在身份验证票据的用户数据中添加了角色信息。默认情况下,FormsAuthenticationTicket与"Users"一起工作,而不是与"Roles"一起工作,所以[Authorize(Roles= "Adminstrador")]
将导致未授权。为了使用角色,您需要从AuthTicket中将角色添加到HttpContext.User
中。
解决方法:
在控制器中添加以下方法:
protected override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext.HttpContext.User != null) { if (filterContext.HttpContext.User.Identity.IsAuthenticated) { if (filterContext.HttpContext.User.Identity is FormsIdentity) { FormsIdentity id = (FormsIdentity)HttpContext.User.Identity; FormsAuthenticationTicket ticket = id.Ticket; string userData = ticket.UserData; string[] roles = userData.Split(','); HttpContext.User = new GenericPrincipal(HttpContext.User.Identity, roles); } } } }
您还可以创建相同的授权过滤器,以便在整个应用程序中使用相同的授权逻辑。
另外,您还可以创建自定义的授权属性,并重写HandleUnauthorizedRequest和AuthorizeCore方法,以获得所需的输出。
关于如何添加自动消息以在访问被拒绝时显示,您可以在自定义授权属性中的HandleUnauthorizedRequest方法中执行相关逻辑。
问题的出现原因:原始的代码中,只检查了用户是否通过身份验证,而没有检查用户是否具有特定角色。这可能导致用户无法访问特定角色所需的方法。
解决方法:修改代码,使用User.IsInRole方法来检查用户是否具有特定角色。这样可以确保只有拥有特定角色的用户才能访问该方法。
以下是修改后的代码示例:
public ActionResult Login() { if (User.IsInRole("ProvideASpecificRoleHere")) return RedirectToAction("Index", "Home"); return View(); }
这样修改后,只有具有特定角色的用户才能被重定向到"Index"方法,否则将返回视图。
这种修改可以确保只有具有特定角色的用户才能访问该方法,而不会取消整个控制器的授权。
希望这个解决方法对您有帮助。感谢您的提问!
附加问题:如何在C# Web API中实现身份验证和基于角色的授权?
您可以在以下链接中找到关于如何在C# Web API中实现身份验证和角色授权的信息: