ASP.NET Core - Authorization Using Windows Authentication
That seems you want to use claims-based authorization via policies . After setting windows authentication in your application , you could add custom claim to ClaimsPrincipal ,check user's identity and confirm which permission current user has :
You can add a claims transformation service to your application:
class ClaimsTransformer : IClaimsTransformation { public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { var id = ((ClaimsIdentity)principal.Identity); var ci = new ClaimsIdentity(id.Claims, id.AuthenticationType, id.NameClaimType, id.RoleClaimType); if (ci.Name.Equals("name")) { ci.AddClaim(new Claim("permission", "readOnly")); } else { ci.AddClaim(new Claim("permission", "write")); } var cp = new ClaimsPrincipal(ci); return Task.FromResult(cp); } }
Add to Startup.cs(.net Core 2.0) :
services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
Set your policy :
services.AddAuthorization(options => { options.AddPolicy("Readonly", policy => policy.RequireClaim("permission", "readOnly")); options.AddPolicy("Write", policy => policy.RequireClaim("permission", "write")); });
Restrict access to a controller or action by requiring this policy:
[Authorize(Policy = "Write")] public IActionResult Contact() { ViewData["Message"] = "Your contact page."; return View(); }
If you have already add groups(write,readonly) in your AD and add the related users to group , you can also check the groups :
public static class Security
{
public static bool IsInGroup(this ClaimsPrincipal User, string GroupName)
{
var groups = new List<string>();
var wi = (WindowsIdentity)User.Identity;
if (wi.Groups != null)
{
foreach (var group in wi.Groups)
{
try
{
groups.Add(group.Translate(typeof(NTAccount)).ToString());
}
catch (Exception)
{
// ignored
}
}
return groups.Contains(GroupName);
}
return false;
}
}
And use like :
if (User.IsInGroup("GroupName"))
{
}
LCaraway
Updated on July 19, 2022Comments
-
LCaraway almost 2 years
I have configured my web api to work with windows authentication. My goal is essentially to restrict certain actions in my controllers based on a users windows account. Some will be able to preform read actions while others will be able to preform actions that will write to the underlying database. I have found plenty of documentation on how to set up claims based authorization which is the route I think I need to go. What I have not found is how to set this up with windows auth. I think I am missing a middle step such as registering the windows auth as the identity provider?
startup.cs
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddAuthentication(IISDefaults.AuthenticationScheme); services.AddAuthorization(options => { options.AddPolicy("readOnly", policy => policy.RequireClaim(`???????????????????????`)); options.AddPolicy("write", policy => policy.RequireClaim(`???????????????????????`)); }); }
Controller
[Authorize(Policy = "ReadOnly")] public class MyController : Controller { public ActionResult SomeReadOnlyAction() { //Return data from database } [Authorize(Policy = "Write")] public ActionResult AWriteAction() { //Create/Update/Delete data from database } }
I guess another way to ask this question is how do you configure or access claims/roles etc... with windows authentication.
-
LCaraway over 5 yearsThis is great! Where does the
if(User.IsInGroup)...
go? Does it get dropped in theClaimsTransformer
Class? -
LCaraway over 5 yearsOr would you use that as an alternative to the ClaimsTransformer?
-
Nan Yu over 5 years@LCaraway , it depends you , it can be in any class .
-
LCaraway over 5 yearsWhen the
group.Translate()
is ran it returns an exception stating the trust relationship between the workstation and the primary domain has failed... -
Nan Yu over 5 yearsSee how to solve the issue :support.microsoft.com/en-hk/help/2771040/… and support.citrix.com/article/CTX227147
-
Stef Chäser over 4 yearsIsn't the code faster if you translate the AD-GroupName to the SID representation.
IdentityReference sidAdGroup = new NTAccount(GroupName).Translate(typeof(SecurityIdentifier));
then comparing it with the SIDs inwi.Groups
(Instead of translate/cast all wi.Groups to NTAccount?) -
Caesar Tex almost 3 yearsWhy not just use the built in User.IsInRole(AD Group Name) for option 2?
-
jondow about 2 yearsGreat answer, really helpful thanks