Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core with optional authentication/authorization

Tags:

I want to build an ASP.NET Core based WebApi for accessing data from a database. This WebApi could be used in two ways, either as a public WebApi which would need authentication or as a private backend service for a web application. In the latter case there would be no need for authentication since only authenticated users can access the web application and both web application and WebApi will run on the same computer, the WebApi will be hidden to the outside.

Since we need authentication for the first scenario, I will have all public APIs tagged with the Authorize attribute. But for the private scenario I would like to bypass any authentication.

Is there any way I could make authentication optional depending on some flag in the configuration?

Update

speaking of two usage scenarios I mean two completely separate installations! Each one has its own configuration file. The decision whether authentication is needed is to made per installation not per request in a single installation! My goal is to have just one code base and a switch in the configuration.

like image 585
NicolasR Avatar asked Oct 19 '16 22:10

NicolasR


1 Answers

If you bypass authentication, how do you distinguish internal or public requests for api? This causes security bug. So you shouldn't bypass authentication.

If you use openidconnect authentication in mvc application then you can set SaveTokens=true. It enables you to store access token in cookie. When you call api in mvc action you can send this access_token to api.

Another way using two different authentication middleware, one for internal another for public access(This is hard to implement).

I would go with first approach.

Update

To achieve your goal, a tricky way is coming to my mind but i am not sure it is good way:

Create a filter provider:

public class EncFilterProvider : IFilterProvider
{
    public int Order
    {
        get
        {
            return -1500;
        }
    }

    public void OnProvidersExecuted(FilterProviderContext context)
    {
    }

    public void OnProvidersExecuting(FilterProviderContext context)
    {
        // remove authorize filters
        var authFilters = context.Results.Where(x => 
           x.Descriptor.Filter.GetType() == typeof(AuthorizeFilter)).ToList();
        foreach(var f in authFilters)
            context.Results.Remove(f);
    }
}

Then register it conditionally based on config value

  public void ConfigureServices(IServiceCollection services)
  {
      if(config["servermode"] = "internal")
      {
          services.AddScoped<IFilterProvider, EncFilterProvider>();
      }
   }
like image 118
adem caglin Avatar answered Oct 10 '22 23:10

adem caglin