Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authorization now includes code configured policy support. #22

Closed
blowdart opened this issue May 8, 2015 · 15 comments
Closed

Authorization now includes code configured policy support. #22

blowdart opened this issue May 8, 2015 · 15 comments

Comments

@blowdart
Copy link
Member

@blowdart blowdart commented May 8, 2015

ASP.NET authorization now supports code based policies. We provide implementations to support claims based authorization and the ability to express your own policies in code. An authorization policy must contain one or more requirements.

Policy configuration is done within ConfigureServices(...) within Startup.cs.

A simple policy to check for the presence of a claim would be configured as follows

services.ConfigureAuthorization(options =>
{
    options.AddPolicy("MustBeGroot", policy => policy.RequireClaim("IAmGroot"));
}

and would be applied as [Authorize(Policy="MustBeGroot")].

You can also specify a list of comma separated values as part of the claim requirement, for example

options.AddPolicy("MustBeGroot", policy => policy.RequireClaim("Permissions", "Read,Update"));

which would pass authorization if the Permissions claim had a value or either Read or Update.

A more complicated requirement would involve implementing IAuthorizationRequirement and an AuthorizationHandler. For example if your identity had a DateOfBirth claim and you wanted to implement a minimum age requirement it could look like

public class MinimumAgeRequirement : AuthorizationHandler<MinimumAgeRequirement>, IAuthorizationRequirement
{
    public MinimumAgeRequirement(int age)
    {
        MinimumAge = age;
    }

    protected int MinimumAge { get; set; }

    public override void Handle(AuthorizationContext context, MinimumAgeRequirement requirement)
    {
        if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth))
        {
            return;
        }

        var dateOfBirth = Convert.ToDateTime(context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value);

        int calculatedAge = DateTime.Today.Year - dateOfBirth.Year;
        if (dateOfBirth > DateTime.Today.AddYears(-calculatedAge))
        {
            calculatedAge--;
        }

        if (calculatedAge >= MinimumAge)
        {
            context.Succeed(requirement);
        }
    }
}

You could then configure it

options.AddPolicy("Over21", 
    policy => policy.Requirements.Add(new Authorization.MinimumAgeRequirement(21)));

and apply it via [Authorize(Policy="Over21")].

Finally you can use policy to limit the authentication schemes checked during authorization, for example

options.AddPolicy("WebApi", policy =>
{
     policy.ActiveAuthenticationSchemes.Add("Bearer");
     policy.RequireAuthenticatedUser();
});

would only allow requests which provide an identity to Bearer middleware to access the resource behind them.

@timmydo
Copy link

@timmydo timmydo commented May 8, 2015

you mean [Authorize(Policy="MustBeGroot")]?

@blowdart
Copy link
Member Author

@blowdart blowdart commented May 8, 2015

I did. Corrected. Thanks. More formal documentation will be coming in the next few weeks.

@sandorfr
Copy link

@sandorfr sandorfr commented May 9, 2015

You mentioned that a policy can contain one or more requirement, but I'm under the impression that it is a must.

@blowdart
Copy link
Member Author

@blowdart blowdart commented May 9, 2015

And this is why I don't do off the cuff documentation, corrected, thank you.

@leastprivilege
Copy link

@leastprivilege leastprivilege commented May 9, 2015

How do I set a global authZ policy? e.g. all controller require an authenticated user

@aggieben
Copy link

@aggieben aggieben commented May 9, 2015

@leastprivilege I'm doing it like this:

var policyBuilder = new AuthorizationPolicyBuilder(OAuth1AuthenticationDefaults.AuthenticationScheme);
var policy = policyBuilder.Build();

services.ConfigureMvc(options => {
   options.Filters.Add(new AuthorizeFilter(policy));
});
@leastprivilege
Copy link

@leastprivilege leastprivilege commented May 9, 2015

This nulls the Identity property on User if the request is anonymous. So this is either a bug - or that is not the right way of installing a global authZ policy.

@crozone
Copy link

@crozone crozone commented Aug 21, 2015

How can you manually check whether a User meets a given AuthorizationPolicy, outside of the AuthorizeAttribute?

Given that AuthorizationOptions can be injected, is there something like bool allowed = AuthorizationOptions.GetPolicy("SomePolicy").Evaluate((ClaimsPrincipal)User) ?

@damccull
Copy link

@damccull damccull commented Aug 26, 2015

Is it possible for a controller/action to use multiple policies? Like "Bearer" and "MinimumAgeRequirement"?

@XplMarcel
Copy link

@XplMarcel XplMarcel commented Sep 29, 2015

If an Authorize attribute on a Controller has Roles ( [Authorize(Roles = "MyRole"] ), the RolesAuthorizationRequirement gets added automatically to the defaultPolicy.
Would it be possible to replace that requirement with my own RolesRequirement class ?

@Eilon
Copy link
Member

@Eilon Eilon commented Sep 29, 2015

@XplMarcel please log an issue in the https://github.com/aspnet/Security/ repo.

@khellang
Copy link

@khellang khellang commented Feb 15, 2016

Can we please lock this issue and refer to https://github.com/aspnet/Security/ instead?

@MaximRouiller
Copy link

@MaximRouiller MaximRouiller commented Feb 15, 2016

Is it possible to add a discussion thread and lock this?

@blowdart
Copy link
Member Author

@blowdart blowdart commented Feb 15, 2016

This is 9 months old, long before the lock and discuss. I'd hope discussion is done now, so locking.

@blowdart blowdart closed this Feb 15, 2016
@aspnet aspnet locked and limited conversation to collaborators Feb 15, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet