0

I have a list of windows authentication groups like

  • developer_group
  • hr_group
  • qa_group
  • db_group

I want to create a custom attribute to filter which user groups are allowed to execute the API something like this. I am not sure can be done like this.

 [MYcustomattribute(groups = hr_group,qa_group)]
 public ActionResult About()
 {
    ViewBag.Message = "Your application description page.";

    return View();
 }

First I need to get the user and that user's all groups. How do I check the user belongs to that group and allow that user to access the API?

Controller :

namespace AuthenticationSample.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }
        [MYcustomattribute(groups = hr_group,qa_group)]
        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

Filter class:

public class MYcustomattribute : ActionFilterAttribute

{

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        //You may fetch data from database here 
        filterContext.Controller.ViewBag.GreetMesssage = "Execute my filter";
        base.OnResultExecuting(filterContext);
    }


    public static bool IsMemberOfGroup(string userName, string groupName)
    {
        if (string.IsNullOrEmpty(userName))
            return false;

        using (var context = new PrincipalContext(ContextType.Domain))
        {
            using (var user = UserPrincipal.FindByIdentity(context, userName))
            {
                if (user != null)
                {
                    var groups = user.GetGroups();
                    foreach (var group in groups)
                    {
                        if (group.Name.Trim().ToUpper() == groupName.Trim().ToUpper())
                            return true;
                    }
                }
            }
        }

        return false;
    }
}
hawkstrider
  • 4,141
  • 16
  • 27
Nav
  • 71
  • 13

1 Answers1

0

You can modify the code below to implement the structure as you described in your question.

public class MyCustomAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (context.HttpContext.Session != null)
            {
                var request = context.HttpContext.Session["User"] as User;
                if (request != null)
                {
                    if (request.UserGroups.Contains("some_group"))
                    {
                        //do something
                    }

                    if (request.UserGroups.Contains(""))
                    {
                        // do something else
                    }

                }
                else
                {
                    //No group info, kinda BadRequest!
                    filterContext.Result = new RedirectResult("/index.html");
                }
            }
        }

The idea behind is that you can deny any requests from unwanted group of people as redirecting them to some page or returning bad request kind of message. Also, you can try to modify user class as shown below to get group informations easily (just a suggestion). Hope this helps you.

public class User
{
    //....
    //....
    //User Attributes
    public List<string> UserGroups { get; set; }
}

Lastly, you can apply this attribute as follows.

    [MyCustom]
    public IActionResult YourControllerMethod()
    {
        return View();
    }

Edit: To get object from HttpClient you can check this out in case of getting null HttpContext session.

Hasan
  • 1,243
  • 12
  • 27
  • what is the var request = context.HttpContext.Session["User"] as User; request is coming null. – Nav Dec 19 '18 at 19:26
  • I was trying to demonstrate to cast your request parameter as User class. I do not know about full project structure and also why you can not get request parameter properly but in order to achieve what you want you should intercept your http request. Maybe you should try to read HttpClient.Request's body to get request object. – Hasan Dec 19 '18 at 19:53