Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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);
    }
like image 825
devnate Avatar asked Jul 10 '14 20:07

devnate


2 Answers

You will need to modify HelpController.cs and add the following method:

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:

return View(FilteredDescriptions());
like image 168
Stanislav Avatar answered Oct 20 '22 15:10

Stanislav


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

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

    if(User.IsInRole("user"))
    {
        return "Text for user";
    }
}
like image 23
Rajdeep Dosanjh Avatar answered Oct 20 '22 15:10

Rajdeep Dosanjh