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.
Authentication is the process of determining a user's identity. Authorization is the process of determining whether a user has access to a resource. In ASP.NET Core, authentication is handled by the authentication service, IAuthenticationService, which is used by authentication middleware.
a) To create a web api project in windows authentication mode, follow below steps: After choosing ASP.Net Web Application, select Web API template and from the right side click Change Authentication button and select Windows Authentication.
Authorization in ASP.NET Core is controlled with AuthorizeAttribute and its various parameters. In its most basic form, applying the [Authorize] attribute to a controller, action, or Razor Page, limits access to that component to authenticated users. Now only authenticated users can access the Logout function.
On the taskbar, click Start, and then click Control Panel. In Control Panel, click Programs and Features, and then click Turn Windows Features on or off. Expand Internet Information Services, then World Wide Web Services, then Security. Select Windows Authentication, and then click OK.
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"))
{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With