jltrem jltrem - 8 days ago 9
ASP.NET (C#) Question

custom AuthorizeAttribute in ASP.NET 5 MVC 6

I'm trying to make a custom authorization attribute in ASP.NET vNext. In previous versions it was possible to override

bool AuthorizeCore(HttpContextBase httpContext)
. But this no longer exists in
AuthorizeAttribute
. Other answers on SO appear to be based on an earlier version of vNext. I'm using beta4.

What is the current approach to make a custom AuthorizeAttribute?

What I am trying to accomplish: I am receiving a session ID in the Header Authorization. From that ID I'll know whether a particular action is valid.

Answer

I'm the asp.net security person. Firstly let me apologise that none of this is documented yet outside of the musicstore sample or unit tests, and it's all still being refined in terms of exposed APIs.

We don't want you writing custom authorize attributes. If you need to do that we've done something wrong. Instead you should be writing authorization requirements.

Authorization acts upon Identities. Identities are created by authentication.

You say in comments you want to check a session ID in a header. Your session ID would be the basis for an identity. If you wanted to use the Authorize attribute you'd write an authentication middleware to take that header and turn it into an authenticated ClaimsPrincipal. You would then check that inside an authorization requirement. Authorization requirements can be as complicated as you like, for example here's one that takes a date of birth claim on the current identity and will authorize if the user is over 18;

public class Over18Requirement : AuthorizationHandler<Over18Requirement>, IAuthorizationRequirement
{
        public override void Handle(AuthorizationContext context, Over18Requirement requirement)
        {
            if (!context.User.HasClaim(c => c.Type == ClaimTypes.DateOfBirth))
            {
                context.Fail();
                return;
            }

            var dateOfBirth = Convert.ToDateTime(context.User.FindFirst(c => c.Type == ClaimTypes.DateOfBirth).Value);
            int age = DateTime.Today.Year - dateOfBirth.Year;
            if (dateOfBirth > DateTime.Today.AddYears(-age))
            {
                age--;
            }

            if (age >= 18)
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
        }
    }
}

Then in your ConfigureServices() function you'd wire it up

options.AddPolicy("Over18", 
    policy => policy.Requirements.Add(new Authorization.Over18Requirement()));

And finally apply it to a controller or action method with

[Authorize(Policy = "Over18")]
Comments