Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows Authentication - require additional password for special users

I am developing an intranet asp.net core web api application. The requirements for authentications are:

  • REQ1 - when user which is trying to access the website is not in Active Directory's special group (let's name it "commonUsers") it is simply not authorized
  • REQ2 - when user which is trying to access the website is in Active Directory's group "commonUsers" is is authorized and a web resource is returned
  • REQ3 - when user which is trying to access the website is in Active Directory's group "superUser", it need to be prompted for his domain password once again (because it tries to access some very restricted resources)

Now, what I have so far:

  • My service is hosted using http.sys server in order to support windows authentication.
  • I am using claims transformer middlewere in order to check the user's Active Directory group, let's say something like this:

    public class ClaimsTransformer : IClaimsTransformation {
    private readonly IAuthorizationService _authorizationService;
    public ClaimsTransformer(IAuthorizationService authorizationService)
    {
        _authorizationService = authorizationService;
    }
    
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        _authorizationService.Authorize(principal as  IHmiClaimsPrincipal);
        return Task.FromResult(principal);
    }}
    
  • I have specified a special policies also in my service configuration, for instance something like that:

    services.AddAuthorization(options =>
        {
            options.AddPolicy("TestPolicy", policy => 
                                       policy.RequireClaim(ClaimTypes.Role, "TestUser"));
            options.AddPolicy("TestPolicy2", policy => 
                                       policy.RequireClaim(ClaimTypes.Role, "SuperUser"));
        });
  • I am using [Authorize] attribute with specific policy in order to restrict access to specific resources based on policies

Now the question is, how should I satisfy REQ3?

like image 747
niao Avatar asked May 06 '19 18:05

niao


People also ask

What is Windows Authentication password?

Windows authentication (formerly named NTLM, and also referred to as Windows NT Challenge/Response authentication) is a secure form of authentication because the user name and password are hashed before being sent across the network.

How do you implement Windows Authentication How do you specify roles and permissions to the users?

To set up your ASP.NET application to work with Windows-based authentication, begin by creating some users and groups. Within your Windows operating system, go to "Control Panel" -> "User Accounts" -> "Manage another account" -> "Create a new account" then choose "Add or Remove User".

How does Windows domain authentication work?

Here's how the authentication process goes: The client requests an authentication ticket from the AD server. The AD server returns the ticket to the client. The client sends this ticket to the Endpoint Server. The Server then returns an acknowledgment of authentication to the client.

Does Kestrel support Windows Authentication?

Authentication. Negotiate NuGet package can be used with Kestrel to support Windows Authentication using Negotiate and Kerberos on Windows, Linux, and macOS. Credentials can be persisted across requests on a connection.


1 Answers

I think I would try to use MVC Filters : https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2#authorization-filters

Filters run after all Middleware, but before the Action. This will allow you to control the redirect to credentials page just for specific actions or controllers. Whilst normally this is not the recommended method for authorization, I think it fits your requirements for a hybrid secondary authentication.

public class SuperUserFilter : Attribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        if (context.HttpContext.Request.Cookies.TryGetValue("SuperUserCookie", out string cookieVal))
        {
            if (!IsValidCookie(cookieVal))
                context.Result = LoginPage(context);

        }
        else
        {
            context.Result = LoginPage(context);
        }
    }

    private bool IsValidCookie(string cookieVal)
    {
        //validate cookie value somehow
        // crytpographic hash, store value in session, whatever
        return true;
    }

    private ActionResult LoginPage(AuthorizationFilterContext context)
    {
        return new RedirectToActionResult("SuperUser", "Login",
            new {redirectUrl = context.HttpContext.Request.GetEncodedUrl()});
    }
}

Then you create a Login Controller

public class LoginController : Controller
{    
    [HttpGet]    
    public IActionResult SuperUser(string redirectUrl)
    {
        // return a page to enter credentials
        // Include redirectUrl as field
    }

    [HttpPost]
    public IActionResult SuperUser(LoginData loginData)
    {
        // Validate User & Password
        Response.Cookies.Append("SuperUserCookie", "SomeValue");
        return Redirect(loginData.RedirectUrl);
    }
}

Then you can decorate specific actions (or controllers) as required:

public class MyController : Controller
{
    [HttpGet]
    [SuperUserFilter]
    public IActionResult MySensitiveAction()
    {
        // Do something sensitive
    }
}
like image 82
ste-fu Avatar answered Oct 19 '22 10:10

ste-fu