【问题标题】:How to create and implement an authorization filter in a .NET Core application如何在 .NET Core 应用程序中创建和实现授权过滤器
【发布时间】:2019-08-15 22:17:08
【问题描述】:

我试图弄清楚如何在 .Net Core 2.1 应用程序中处理请求之前使用授权过滤器来授权用户。

我公司的用户在使用需要身份验证的内部 Web 应用程序时会通过 SSO 服务器重定向。然后,SSO 服务器将请求转发到 Web 应用程序,请求标头中包含身份验证和授权信息。目前,我的所有控制器操作方法都包含一个条件语句,用于检查请求标头中提供的用户角色是否包含执行操作所需的任何可能角色。使用授权过滤器似乎是一种更简洁的方法,但是尽管我看过所有文档和教程,但我仍然无法弄清楚如何实现该技术。

这是我目前用来检查用户是否有权执行某项操作的方法:

using System;

namespace MyApp
{
    public static class Authorization
    {
        public static bool IsAuthorized(string usersRoles, params string[] authorizedRoles)
        {
            if (usersRoles != null)
            {
                foreach (string authorizedRole in authorizedRoles)
                {
                    if (usersRoles.Contains(",MYAPP?" + authorizedRole))
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}

下面是一个控制器方法的示例,它将用户角色从请求标头和可能的角色列表传递给“IsAuthorized”方法,以检查用户是否有权执行该操作:

public IActionResult Index()
{
    if (!Authorization.IsAuthorized(Request.Headers["COMPANYACCESSROLES"], "TYPE1_USER", "TYPE2_USER", "TYPE3_USER"))
    {
        ViewData["Message"] = "Not Authorized";
        return View("MyAppMessage");
    }
    // Do stuff to complete the action requested here
    return View();
}

请求标头中包含的角色如下所示:

SOMEAPP,SOMEAPP?SOMEROLE1,SOMEAPP?SOMEROLE2,MYAPP,MYAPP?TYPE2_USER,MYAPP?TYPE2_RO,ANOTHERAPP,ANOTHERAPP?ANOTHERROLE1

我希望能够删除我目前在每个控制器方法开头的条件语句,并改用这样的授权过滤器:

[Authorize(Roles = "TYPE1_USER", "TYPE2_USER", "TYPE3_USER")]
public IActionResult Index()
{
    // Do stuff to complete the action requested here
    return View();
}

任何帮助将不胜感激。

【问题讨论】:

  • Request.Headers["COMPANYACCESSROLES"] 与安全无关。它表明客户端可以设置它想要的任何角色,而服务器将无法检测到更改。在 Authorization 标头中设置不记名令牌会更安全。在这种情况下,您可以根据需要使用 Authorize 属性为每个控制器/方法指定允许的角色。作为documented.
  • 请求标头中提供的访问角色来自对我公司的用户进行身份验证的 SSO 服务器。我已经更新了我的问题以使其更清楚。

标签: c# .net-core authorization


【解决方案1】:

当来自 SSO 服务器的请求标头中包含用户的访问角色时,可以使用操作过滤器而不是授权过滤器来允许访问。将嵌套在 TypeFilterAttribute 类中的 IActionFilter 类添加到项目中就可以了:

public class AuthorizedRoles : TypeFilterAttribute
{
    public AuthorizedRoles(params string[] authorizedRoles) : base(typeof(AuthorizationFilter))
    {
        Arguments = new object[] { authorizedRoles };
    }

    private class AuthorizationFilter: IActionFilter
    {
        private readonly ILogger _logger;
        private readonly string[] _authorizedRoles;

        public AuthorizationFilter(ILoggerFactory loggerFactory, string[] authorizedRoles)
        {
            _logger = loggerFactory.CreateLogger<AuthorizedRoles>();
            _authorizedRoles = authorizedRoles;
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            string usersRoles = context.HttpContext.Request.Headers["BOEINGACCESSROLES"];
            if (!Authorization.IsAuthorized(usersRoles, _authorizedRoles))
            {
                context.Result = new ViewResult { ViewName = "NotAuthorized" };
            }
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
        }
    }
}

请注意,我不知道从 IActionFilter 类中将 ViewData 信息传递到 Razor 页面的好方法,因此当用户未被授权时,而不是设置 ViewData["Message"] = "Not Authorized" 并调用“MyAppMessage”视图,从OnActionExecuting 方法调用静态“NotAuthorized”视图。

现在可以在控制器方法之上(或在整个控制器类之上,如果需要)使用这样的过滤器,以仅允许具有至少一个指定角色的用户访问:

[AuthorizedRoles("TYPE1_USER", "TYPE2_USER", "TYPE3_USER")]
public IActionResult Index()
{
    // Do stuff to complete the action requested here
    return View();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    相关资源
    最近更新 更多