Search code examples
authorizationasp.net-coreaspnet-contrib

write single API accessible through asp.net identity user and bearer token both


I have created asp.net mvc 6 application and configured asp.net identity users using entity framework 7 working fine. Then I added AspNet.Security.OpenIdConnect.Server token provider server that is also working fine.

Then I created an api controller as follows:

[Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET: api/values
        [Authorize(Policy = "SomePolicy")]
        [HttpGet]
        public IEnumerable Get()
        {
            return new string[] { "value1", "value2" };
        }
    }

Question: I want to configure authorization in such a way so that either bearer token or asp.net identity user is valid (and belong to some role), I want to allow the user to access API.

Here is what I tried in startup.cs:

 services.AddAuthorization(options => {
                // Add a new policy requiring a "scope" claim
                // containing the "api-resource-controller" value.
                options.AddPolicy("API", policy => {
                    policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
                    policy.RequireClaim(OpenIdConnectConstants.Claims.Scope, "offline_access");                                        
                });                
            });

then if I add [Authorize(Policy="API")] to my api controller, that is ONLY respecting bearer tokens, not identity users.

Any help is appreciated!


Solution

  • policy.AddAuthenticationSchemes supports multiple schemes, so you could - in theory - do something like that:

    services.AddAuthorization(options => {
        options.AddPolicy("API", policy => {
            policy.AddAuthenticationSchemes(
                /* Scheme 1: */ JwtBearerDefaults.AuthenticationScheme,
                /* Scheme 2: */ typeof(IdentityCookieOptions).Namespace + ".Application");
        });
    });
    

    Note: typeof(IdentityCookieOptions).Namespace + ".Application" is the default authentication scheme used by ASP.NET Identity 3: https://github.com/aspnet/Identity/blob/3.0.0-rc1/src/Microsoft.AspNet.Identity/IdentityCookieOptions.cs#L61

    Alternatively, you could also remove the policy.AddAuthenticationSchemes call and configure the bearer and cookies middleware to use automatic authentication (AutomaticAuthenticate = true, which is the default value for the cookies middleware, but not for the JWT middleware).


    In practice, it's absolutely not recommended as it defeats the whole purpose of using bearer-only authentication: mitigating XSRF attacks. If you really want to support cookies + bearer authentication, you should strongly consider implementing XSRF countermeasures.