MVC Authorize work with attribute without logging out
I have a controller class that only a specific Active Directory group should have access to.
[Authorize(Roles = @"Domain\GroupName")]
public class AdminToolsController : Controller
{
...
}
Now that I'm testing .. I'm from the group right now .. but if I add myself .. and I try to access anything in this controller, I am still asked to login and my credentials are not working. However .. if I add myself .. then log out .. then log back in .. then try to access anything in this controller, it recognizes me and allows me to access.
Is there a way to do this instantly? Sense, can I add myself to the group and successfully access any of the methods inside the controller without having to log out and log in?
UPDATE
I have edited Camilo Terevinto below. Their answer for some reason .. whenever I added or removed myself from a particular group .. that group would not be part of a variable groups
.
Here's my update:
public class AuthorizeByActiveDirectoryGroups : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var roles = Roles.Split(',');
using (var domainContext = new PrincipalContext(ContextType.Domain, "domainname"))
{
var user = httpContext.User.Identity.Name;
using (var domainUser = UserPrincipal.FindByIdentity(domainContext, httpContext.User.Identity.Name))
{
var adgroup = GroupPrincipal.FindByIdentity(domainContext, "Domain\\GroupName");
bool member = domainUser.IsMemberOf(adgroup);
var groups = domainUser.GetAuthorizationGroups();
return member;
}
}
}
}
source to share
IIRC, roles are only retrieved once when you log in with Windows default authentication, so you can use a custom attribute to always get the latest data.
Since this always checks for AD values, you can use some caching and update the values ββonly when needed, but that depends on your specific case.
Note: I don't have VS right now, so there might be a spelling issue
public class AuthorizeByActiveDirectoryGroupsAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var roles = Roles.Split(",");
using (var domainContext = new PrincipalContext(ContextType.Domain))
{
using (var domainUser = UserPrincipal.FindByIdentity(domainContext, httpContext.User.Identity.Name))
{
var groups = domainUser.GetAuthorizationGroups();
return groups
.Select(x => x.Name) // the group name
.Any(x => roles.Contains(x)); // any group is one of the specified in the Roles property of the attribute
}
}
}
}
So, you would use it like:
[AuthorizeByActiveDirectoryGroups(Roles = "Group1,Group2")]
public ActionResult Index()
{
return View();
}
source to share
On Windows, if a user is assigned or removed from a group, this change takes effect at the next logon. This behaviorWindows. Hence, after logging out and logging in, it works as you expected.
When you double click on a group on a Windows machine, it has this information at the bottom, which says the change takes effect after you log in.
source to share
If you are using cookies you need to make sure the cookie is recreated with new roles after assigning a new role
var userManager = HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager);
IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;
authenticationManager.SignOut("ApplicationCookie");
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, oAuthIdentity );
add this code right after adding "Domain \ GroupName" role to your user
source to share