2

I have an ASP.Net 5 application using version 1.0.0-rc1-update1 with Windows Authentication. I've implemented a custom policy in my Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    // ... other configuration code

    var viewCharts = new AuthorizationPolicyBuilder()
        .AddRequirements(new ViewChartsRequirement())
        .Build();

    collection.AddAuthorization(opts =>
    {
        opts.AddPolicy(Policy.ViewCharts, viewCharts);
    });

    collection.AddTransient<IAuthorizationHandler, ViewChartsHandler>();

    // ... other configuration code
}

The ViewChartsHandler's Handle method is as follows:

protected override void Handle(
    AuthorizationContext context,
    T requirement)
{
    var identities = _securityRepo.GetIdentitiesForPolicy(_policy);

    // this returns a result when using a web listener, but
    // never finds a match when using IIS Express
    var matchingIdentity = identities.FirstOrDefault(role => context.User.IsInRole(role));

    if (!string.IsNullOrWhiteSpace(matchingIdentity))
    {
        context.Succeed(requirement);
    }
}

When using a web listener as shown in this answer, the code above works. However, when using IIS Express it never finds a matchingIdentity.

Things to note:

  1. My IIS Express is configured to use Windows Authentication, and deny Anonymous Authentication. The bug related to IIS Express and this was fixed in RC1.
  2. The username from Windows is always resolving correctly.
  3. In the Handle code above, context.User is an instance of System.Security.Principal.WindowsPrincipal when using a web listener, but when using IIS Express it is a System.Security.Claims.ClaimsPrincipal.
  4. I have forwardWindowsAuthToken="true" set in my web.config.

I think this is a role provider problem, but I am at a loss as to how to correct it.

Community
  • 1
  • 1
Will Ray
  • 10,621
  • 3
  • 46
  • 61

3 Answers3

1

I'm using the following code to successfully check for role membership on RC1, however note that it does not resolve group names (probably due to the problems referred to by @blowdart), I have to supply the group names as SIDs:

// Set up authorisation policies from the configured AD group lists.
// NOTE: Currently this only works with SIDs if hosting using Kestrel 
// behind IIS, not friendly group names.
var viewerGroups = Configuration.GetSection("Groups:Viewer").Value.Split(',');
var adminGroups = Configuration.GetSection("Groups:Admin").Value.Split(',');
services.AddAuthorization(auth =>
{
    auth.AddPolicy("viewer", policy =>
    {
        policy.RequireRole(viewerGroups);
    });
    auth.AddPolicy("admin", policy =>
    {
        policy.RequireRole(adminGroups);
    });
});

I don't know if this will help you, but I thought I'd offer it up in case!

Mark Hughes
  • 7,264
  • 1
  • 33
  • 37
0

Did you add the IISPlatformHandler middleware?

app.UseIISPlatformHandler();

This needs to be ran before app.UseMvc(), app.UseStaticFiles() or any other authentication middleware.

blowdart
  • 55,577
  • 12
  • 114
  • 149
  • Yup! I am using app.UseIISPlatformHandler and invoking it before any UseStatic and UseMvc calls. However, since the authentication handlers are added in the ConfigureServices method, they are invoked before app.UserIISPlatformHandler as ConfigureServices is called before Configure. – Will Ray Mar 14 '16 at 22:02
  • 1
    Oh wait. IsInRole? That's, err, broken in RC1. It is fixed in RC2. – blowdart Mar 14 '16 at 22:12
  • Whoa! Do you have an supporting sources for me look into on that? I can't find anything in the RC2 announcements: https://github.com/aspnet/Announcements/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+milestone%3A1.0.0-rc2 – Will Ray Mar 14 '16 at 23:51
  • 2
    Well I'm the asp.net security person, so I'm the source I can try to find the github issue if you like but I'm off to a conference until Friday. – blowdart Mar 14 '16 at 23:53
  • Ahh, well that's certainly enough for me! I'll be eagerly awaiting the fix in RC2 then! – Will Ray Mar 15 '16 at 00:17
  • Cool, because I'll be damned if I can find the issue now :) – blowdart Mar 15 '16 at 03:00
0

It turns out that User.IsInRole does not function correctly in RC1. (See @blowdart's comments.) This will be fixed in RC2.

The original code will work so long as the line below returns the SIDs for each AD group, as opposed to the friendly names.

// This line must return SIDs instead of friendly names
var identities = _securityRepo.GetIdentitiesForPolicy(_policy);

Update

This was fixed in RC2. The original code works!

Will Ray
  • 10,621
  • 3
  • 46
  • 61