如何将一个控制器的方法授权给一个角色或多个角色,而不会取消整个控制器。

7 浏览
0 Comments

如何将一个控制器的方法授权给一个角色或多个角色,而不会取消整个控制器。

我正试图通过角色限制访问我的控制器的方法,以传统的方式,完整的控制器拒绝了所有角色的用户的身份验证

这是一个带有多个角色的授权属性

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;
    }
}

0
0 Comments

问题的出现原因:

根据提供的代码,您在身份验证票据的用户数据中添加了角色信息。默认情况下,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方法中执行相关逻辑。

0
0 Comments

问题的出现原因:原始的代码中,只检查了用户是否通过身份验证,而没有检查用户是否具有特定角色。这可能导致用户无法访问特定角色所需的方法。

解决方法:修改代码,使用User.IsInRole方法来检查用户是否具有特定角色。这样可以确保只有拥有特定角色的用户才能访问该方法。

以下是修改后的代码示例:

public ActionResult Login()
{
   if (User.IsInRole("ProvideASpecificRoleHere"))
      return RedirectToAction("Index", "Home");
   return View();
}

这样修改后,只有具有特定角色的用户才能被重定向到"Index"方法,否则将返回视图。

这种修改可以确保只有具有特定角色的用户才能访问该方法,而不会取消整个控制器的授权。

希望这个解决方法对您有帮助。感谢您的提问!

附加问题:如何在C# Web API中实现身份验证和基于角色的授权?

您可以在以下链接中找到关于如何在C# Web API中实现身份验证和角色授权的信息:

stackoverflow.com/questions/54597216/...

0