Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authenticate a site/app to access a Web API Service

Brief question: I've a Web API Service in .NET, and a Site made only with HTML and AngularJS.

How can authorize to my service ONLY my web?


I'm looking for a secure answer to a problem that seems to be common but is not. I read a lot of answers, ideas and every kind of things in the late days, but I couldn't find the solution.

Let's suppose I've a Web Api Service (the lastest one) from MS. So I have to application that need consumes it. Let's define two scenarios.

Scenario 1:

In the same IIS, I've an ASP.NET MVC 3/4 with the particularity that all MVC work is on the client side, made by AngularJS, so the App points directly from JavaScript to the Web Api Service.

Scenario 2:

I've a third party application that points directly to the Web Api Service, and is locate in other network/site/anything but related.

So, my question is:

How can authenticate both systems, in order to the Web Api Service gives access to both system (I don't care if is the same way or not), and not give access for example to a guy with a REST client, and logged to the site with user/pass authorization? I hope these both examples gave the idea of the point what I'm interested.

Please comment below anything you need to improve this question in a better way!

By the way, no, obfuscation can not be used. I thought in something like a refreshing token but I can't figure it.

like image 834
Leandro Bardelli Avatar asked May 18 '14 02:05

Leandro Bardelli


People also ask

How do you authenticate web API?

Web API assumes that authentication happens in the host. For web-hosting, the host is IIS, which uses HTTP modules for authentication. You can configure your project to use any of the authentication modules built in to IIS or ASP.NET, or write your own HTTP module to perform custom authentication.

How does authentication and authorization work in web API?

The authentication and authorization mechanism in such a site is simple. After the user logs into the website, a single database holding user information verifies their identity. A session is created on the server, and all subsequent requests use the session to identify the user without another login required.

Which authentication is best for web API?

OAuth (specifically, OAuth 2.0) is considered a gold standard when it comes to REST API authentication, especially in enterprise scenarios involving sophisticated web and mobile applications. OAuth 2.0 can support dynamic collections of users, permission levels, scope parameters and data types.

What are the types of authentication in web API?

There are three ways to authenticate users when calling a web API: API key authentication. Basic authentication. Session-based authentication.


2 Answers

How I would set up authentication with your Scenario 1:

I will force the static files to go through the server in order to ensure authentication

Web.config

<compilation>
    <buildProviders>
        <add extension=".html" type="System.Web.Compilation.PageBuildProvider" />
        <add extension=".htm" type="System.Web.Compilation.PageBuildProvider" />
    </buildProviders>
</compilation>

<system.webServer>
     <handlers>
         <add name="HTML" path="*.html" verb="GET, HEAD, POST, DEBUG"   type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" />
         <add name="HTM" path="*.htm" verb="GET, HEAD, POST, DEBUG" type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" />
     </handlers>
</system.webServer>

This will allow me to set up <authentication> and <authorization> in my web.config like:

<authorization>
  <allow roles="demo" />
</authorization>

or

 <authorization>
   <deny users="?" />
 </authorization>

Additionally I will set up my login page:

<authentication mode="Forms">
      <forms  path="/" loginUrl="~/login"..

For Scenario 2:

Probably you will need to enable CORS, if it is the case you will need to:

Set the config option config.EnableCors(); in your Register method; you will also need to enable CORS in your ApiController by using [EnableCors] attribute along with the declaration of the controller, here is an example how I do it:

 [EnableCors(origins: "http://localhost:49595", headers: "*", methods: "*")]
 public class ValuesController : ApiController
 {
 ...

Finally to secure the WebApi we will need to use an attribute [Authorize] in the controllers and most likely you will need to define your custom authentication method to authorize your second callers. You could follow these steps:

  • How to set up WebApi Custom Authorization
like image 170
Dalorzo Avatar answered Sep 27 '22 22:09

Dalorzo


Not exactly an answer to the question but what I want to say is too long for a comment, so...

There are various ways to secure a RESTful service, but if you want to restrict access to it you mainly have two approaches:

  • use the service only from an internal network or through a VPN of some sort (i.e. control the environment over which the service is accessed and allow access only from some specific sources);
  • have the service exposed to the public but then have the application or server drop any requests that don't meet some requirements (i.e. not authenticated, missing tokens, bad signatures etc).

Depending on what you are doing, none of the above could work.

What you want (as I understand from your question) is to limit the clients accessing your service to just two. Of the top of my head I can only think of HTTPS with mutual authentication. You use client side certificates to authenticate the client. IIS will handle the connection so if your clients make a request without presenting a certificate the request is rejected. Nobody can access your service unless they have a client certificate provided by you.

So it's a matter of issuing one certificate for each client. This works for the third party app but it might be impossible to implement because of the browsers accessing your API directly. This will mean you need to install a certificate for each browser accessing your MVC application or move access to the API on the MVC server side and no longer call it directly from AngularJS. If you can do either of that it's fine, otherwise it's back to the drawing board...

Hope this helps! And if you find a suitable solution please post it as an answer on SO.

like image 44
Bogdan Avatar answered Sep 27 '22 22:09

Bogdan