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.
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.
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.
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.
There are three ways to authenticate users when calling a web API: API key authentication. Basic authentication. Session-based authentication.
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:
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With