0

I want to get Windows logon of the users in GrantResourceOwnerCredentials method of Provider class and validate them. I tried all the possible ways like below, but no luck.

  1. System.Security.Principal.WindowsIdentity.GetCurrent().Name --> It is returning the server name
  2. Request.LogonUserIdentity --> null (It cant be accessed before authentication)
  3. HttpContext.Current.User --> null
Ajay Agrawal
  • 145
  • 2
  • 10
  • Perhaps this will help: https://stackoverflow.com/a/32083020/11266990 – Amélie Dupré Jun 12 '19 at 14:34
  • I have seen this article. It is getting the value in Invoke method, but I am not sure where this method is being called. If you can tell me, then it would be great. I want the logon specifically in GrantResourceOwnerCredentials method so that I can validate the user before generating token. – Ajay Agrawal Jun 13 '19 at 06:32
  • I'm afraid I've not worked with Windows logon in Web API, but if you're using GrantResourceOwnerCredentials, I expect the context is passed as a parameter? What does this return: `public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { var username = context.UserName; var password = context.Password; }` (Sorry, I can't seem to be able to format the code properly in a comment) – Amélie Dupré Jun 13 '19 at 07:56
  • Username and password are the values sent by client. – Ajay Agrawal Jun 13 '19 at 09:52

1 Answers1

1

From what I understand, if you're only using Windows Authentication, you don't need to worry about GrantResourceOwnerCredentials. Are you trying to use the token authentication as well as the Windows authentication? you should only use Windows Authentication for a Web Api that is going to run on your intranet.

Forgive me if I say things you already know, but from the research I've done, and my thanks go to Dominick Baier on pluralsight, you need to:

  • Install the Microsoft.Owin and Microsoft.Owin.Security.OAuth nuget packages
  • Set Windows Authentication to "Enabled" on the Project (F4 properties window) or in the config file
  • Make sure you have the [Authorize] attribute on your controller and inherit from the ApiController
  • Specifically implement the Owin middleware (you will need to create three classes and make sure they are configured in the startup.cs class) Have a look at the following code:

1st Middleware class: declare the function

public class ClaimsTransformationOptions
{
    public Func<ClaimsPrincipal, Task<ClaimsPrincipal>> ClaimsTransformation { get; set; }
}

2nd Middleware class: this is where the Invoke method is

public class ClaimsTransformationMiddleware
{
    readonly ClaimsTransformationOptions _options;
    readonly Func<IDictionary<string, object>, Task> _next;

    public ClaimsTransformationMiddleware(Func<IDictionary<string, object>, Task> next, ClaimsTransformationOptions options)
    {
        _next = next;
        _options = options;
    }

    public async Task Invoke(IDictionary<string, object> env)
    {
        // use Katana OWIN abstractions (optional)
        var context = new OwinContext(env);

        if (context.Authentication != null &&
            context.Authentication.User != null)
        {
            var transformedPrincipal = await _options.ClaimsTransformation(context.Authentication.User);
            context.Authentication.User = new ClaimsPrincipal(transformedPrincipal);
        }

        await _next(env);
    }
}

3rd Middleware class: this is an extension class

public static class ClaimsTransformationMiddlewareExtensions
{
    public static IAppBuilder UseClaimsTransformation(this IAppBuilder app,
        Func<ClaimsPrincipal, Task<ClaimsPrincipal>> transformation)
    {
        return app.UseClaimsTransformation(new ClaimsTransformationOptions
        {
            ClaimsTransformation = transformation
        });
    }

    public static IAppBuilder UseClaimsTransformation(this IAppBuilder app, ClaimsTransformationOptions options)
    {
        if (options == null)
        {
            throw new ArgumentNullException("options");
        }

        app.Use(typeof(ClaimsTransformationMiddleware), options);
        return app;
    }
}

In the startup class:

public void Configuration(IAppBuilder app)
{
    app.UseClaimsTransformation(Transformation);
}
private async Task<ClaimsPrincipal> Transformation(ClaimsPrincipal incoming)
{
    if (!incoming.Identity.IsAuthenticated)
    {
        return incoming;
    }

    var name = incoming.Identity.Name;

    // go to a datastore - find the app specific claims

    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.NameIdentifier, name),
        new Claim(ClaimTypes.Role, "foo"),
        new Claim(ClaimTypes.Email, "foo@foo.com")
    };

    var id = new ClaimsIdentity("Windows");
    id.AddClaims(claims);

    return new ClaimsPrincipal(id);
}

In the Controller (Make sure it has the [Authorize] attribute and inherits from ApiController

public IEnumerable<ViewClaim> Get()
{
        var principal = User as ClaimsPrincipal;
        return  from c in principal.Claims
            select new ViewClaim
            {
                Type = c.Type,
                Value = c.Value
            };
}