简体   繁体   English

基于授权的 ASP.Net Web Api 帮助页面

[英]ASP.Net Web Api Help page based on authorization

I'm using the ASP.Net Web API behind Windows Authentication and using the [Authorize] attribute to dictate what controllers and functions users have access to.我在 Windows 身份验证后面使用 ASP.Net Web API,并使用 [Authorize] 属性来指示用户可以访问哪些控制器和功能。 This works great.这很好用。 The problem is that I would like to have the help area reflect only what the user has been granted for access.问题是我想让帮助区域只反映用户被授予访问权限的内容。 Curious if anyone has achieved this in some fashion.好奇是否有人以某种方式实现了这一目标。 Is this done at the level of the controller, the App Start, or the help controller.这是在控制器、应用程序启动还是帮助控制器级别完成的。

Thanks in advance...提前致谢...

Code snippet of one of my controllers我的控制器之一的代码片段

[Authorize]
public class TaktTimeController : ApiController
{
    private BIDataContainer db = new BIDataContainer();

    // GET api/TaktTime
    [Authorize(Roles="Admins")]
    public IQueryable<TaktTime> GetTaktTimes()
    {
        return db.TaktTimes;
    }

    // GET api/TaktTime/5
    [ResponseType(typeof(TaktTime))]
    [Authorize(Roles = "Admins")]
    public IHttpActionResult GetTaktTime(string id)
    {
        TaktTime takttime = db.TaktTimes.Find(id);
        if (takttime == null)
        {
            return NotFound();
        }

        return Ok(takttime);
    }

You will need to modify HelpController.cs and add the following method:您将需要修改 HelpController.cs 并添加以下方法:

using System.Collections.ObjectModel;

private Collection<ApiDescription> FilteredDescriptions()
{
    var descriptionsToShow = new Collection<ApiDescription>();

    foreach (var apiDescription in Configuration.Services.GetApiExplorer().ApiDescriptions)
    {
        var actionDescriptor = apiDescription.ActionDescriptor as ReflectedHttpActionDescriptor;
        var authAttribute = actionDescriptor?.MethodInfo.CustomAttributes.FirstOrDefault(x => x.AttributeType.Name == nameof(System.Web.Http.AuthorizeAttribute));
        var roleArgument = authAttribute?.NamedArguments?.FirstOrDefault(x => x.MemberName == nameof(System.Web.Http.AuthorizeAttribute.Roles));
        var roles = roleArgument?.TypedValue.Value as string;
        if (roles?.Split(',').Any(role => User.IsInRole(role.Trim())) ?? false)
        {
            descriptionsToShow.Add(apiDescription);
        }
    }
    return descriptionsToShow;
}

And call it from the Index() action:并从 Index() 操作调用它:

return View(FilteredDescriptions());

This can be achieved in razor view something like the following would be what you need.这可以在剃刀视图中实现,如下所示将是您所需要的。

 @if (User.IsInRole("admin"))
 {
     <div>
         <!--Text for admin here-->
     </div>
 }
 @if (User.IsInRole("user"))
 {
     <div>
         <!--Text for user here-->
     </div>
 }

The same logic can be used in WebApi controllers可以在 WebApi 控制器中使用相同的逻辑

public string Get()
{
    if(User.IsInRole("admin"))
    {
        return "Text for admin";
    }

    if(User.IsInRole("user"))
    {
        return "Text for user";
    }
}

Building upon Stanislav's approach, I have added support for AllowAnonymous , username-based authorization, controller attributes and global authorization filters.基于 Stanislav 的方法,我添加了对AllowAnonymous 、基于用户名的授权、控制器属性和全局授权过滤器的支持。

public ActionResult Index()
{
    ViewBag.DocumentationProvider = Configuration.Services.GetDocumentationProvider();
    //return View(Configuration.Services.GetApiExplorer().ApiDescriptions);
    return View(FilteredDescriptions());
}

private Collection<ApiDescription> FilteredDescriptions()
{
    var list = Configuration.Services.GetApiExplorer().ApiDescriptions
        .Where(apiDescription =>
        {
            // action attributes
            if (apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count != 0)
            {
                return true;
            }

            var actionAuthorizeAttributes = apiDescription.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>();

            if (actionAuthorizeAttributes.Count != 0)
            {
                return actionAuthorizeAttributes.All(IsUserAuthorized);
            }

            // controller attributes
            if (apiDescription.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count != 0)
            {
                return true;
            }

            var controllerAuthorizeAttributes = apiDescription.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AuthorizeAttribute>();

            if (controllerAuthorizeAttributes.Count != 0)
            {
                return controllerAuthorizeAttributes.All(IsUserAuthorized);
            }

            // global attributes
            if (apiDescription.ActionDescriptor.Configuration.Filters.OfType<AllowAnonymousAttribute>().Any())
            {
                return true;
            }

            var globalAuthorizeAttributes = apiDescription.ActionDescriptor.Configuration.Filters.OfType<AuthorizeAttribute>().ToList();

            if (globalAuthorizeAttributes.Count != 0)
            {
                return globalAuthorizeAttributes.All(IsUserAuthorized);
            }

            return true;
        })
        .ToList();

    return new Collection<ApiDescription>(list);
}

private bool IsUserAuthorized(AuthorizeAttribute authorizeAttribute)
{
    return User.Identity.IsAuthenticated
        && (authorizeAttribute.Roles == "" || authorizeAttribute.Roles.Split(',').Any(role => User.IsInRole(role.Trim())))
        && (authorizeAttribute.Users == "" || authorizeAttribute.Users.Split(',').Any(user => User.Identity.Name == user));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM