Use both cookie based authentication and token based authentication for api controllers

Viewed 177

We have an application which also has some api controllers that should be called with authentication token and there are some other api/regular controllers which should use open id connect cookie based authentication. Below is the code from Startup.Auth.cs

public void ConfigureAuth(IAppBuilder app)
    {
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseKentorOwinCookieSaver();
        app.UseCookieAuthentication(new CookieAuthenticationOptions()
        { CookieSecure = CookieSecureOption.Always });

        app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(PasswordResetPolicyId));
        app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(SignUpSignInPolicyId));

        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"],
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidAudience = ConfigurationManager.AppSettings["ida:Audience"]
                },
            });
    }

we have one diff windows app which after adding user credentials should call the api controller methods using token. It does call the api method but in response we get a html login page ui code. OK status is received but instead of this login page code we should get the value returned by the api method. This method does not get executed because authentication is somehow creating problem.

1 Answers

I would aim to ensure a clean separation between web and app, along the following lines:

WEB APP CHARACTERISTICS

  • Use a web hosting solution
  • Return OAuth redirects to the caller when requests are not authorized

API CHARACTERISTICS

  • Use an API hosting solution
  • Return 401 responses to the caller when requests are not authorized

This would fix the problem for your desktop application.

CODE SEPARATION

Aim to separate your Web Back End and API code - either physically as separate components, or logically, within the same component. If doing the latter, the convention is often to use an /api root path for API endpoints:

  • /myapp/myWebPage1
  • /myapp/myWebPage2
  • /myapp/api/myOperation1
  • /myapp/api/myOperation2

MICROSOFT SOLUTION

In .Net Core, the Microsoft UseWhen mechanism works quite well, so that you can write code like this:

app.UseWhen(
  ctx => ctx.Request.Path.StartsWithSegments(new PathString("/api")),
  api => app. UseWindowsAzureActiveDirectoryBearerAuthentication()
);
app.UseWhen(
  ctx => !ctx.Request.Path.StartsWithSegments(new PathString("/api")),
  api => app. UseCookieAuthentication()
);

If you are using OWIN based C# the same pattern can be achieved, perhaps via an extension method similar to this.

Related