I'm developing a service that has two components - a web interface and a REST API. I use ASP.NET MVC and ASP.NET Web API, respectively. The two components are hosted on different subdomains of the same domain.
I want the REST API to be used by both external users and the web interface, and I want to simplify authentication as much as possible.
The REST API currently only supports basic authentication.
The web interface uses forms authentication and thus generates an ASPXAUTH cookie. The web interface interacts with the REST API using AJAX calls.
My question to the community is:
How do I authenticate the AJAX calls from the web interface to the
REST API, using the most elegant and secure method?
Some ideas:
Send the ASPXAUTH cookie in the ajax calls (by changing the cookie domain to ".myservice.com" to allow cross-subdomain read) and adding an authentication method in the API that reads the ASPXAUTH. Not sure if this is a great idea, or how to implement this.
Storing the user name and API key in separate cookies. Not really safe unless the values are encrypted/hashed.
Using OAuth in the web interface and rest api, instead of forms + basic authentication?
Ok, I've come up with the following solution:
I've added form authentication to the REST API and made sure not to use IsolateApps in the <machinekey>section of machine.config. This ensures that the REST API can use the same ASPXAUTH cookie. I'm making sure to fall back to basic authentication if no ASPXAUTH cookie is present.
Since there's no way to include the ASPXAUTH cookie in ajax requests to a different subdomain due to the Same-origin policy (even though the cookie's domain is ".myservice.com"), the solution I chose was to add an application (through IIS) to the web interface with the name "api".
The ajax calls now point to "/app.myservice.com/api/..." instead of "https://api.myservice.com/...", and the ASPXAUTH cookie is included and works.
Not sure if this is the best solution, but it's both clean and secure. Only tweak is the sharing of machine keys. If running in a web farm you would need to set the same machine key to all machines.
Related
I have a ASP.NET Core 6 web app. I'm using Identity for an authentication. It is in its simplest form - users need to put credentials in the login page to access parts of aplication.
Now I need to expose one endpoint. It should be accessible by application from a different server. Therefore a solution with redirection to a login page and storing credential in caches doesn't make sense (keep in mind I want to keep it, just add some filtering on a particular api).
Instead I would prefer to allow hitting this enpoint with some kind of token. Another solution that comes to my mind is to whitelist the server of the application not to require authorization.
I don't know which of these are possible or recommended. Will gladly hear your advices.
or must it be on the same server as the app calling it? I am new to web api so i am going through some tutorials, but they all assume the web api is part of the mvc app. Also, they show the calls to the api being done with javascript, but I want to make the calls in my MVC app controller. Is this possible?
You can host a Web API anywhere.
The only special thing to have into account when the Web API isn't in the same server that a web site that uses it, is that, by default, the Web API doesn't accept requests from a different domain. For example, if the web site is in "server1.com" and the Web API in "server2.com", then the calls to the Web API from the web server will be rejected.
If this is the case, you need to configure the Web API server to enable CORS (cross origin resource sharing), so that it accepts requests from a different domain. If you want more info about this, please look at this document:
Enabling Cross-Origin Requests in ASP.NET Web API 2
The Web Api can live wherever you want it to. Is typical to see a limited API used mostly to handle AJAX for the MVC application live with the MVC application, mostly because it makes it simpler to construct URLs to the endpoints. If you host the Web Api externally, then you'll have to hardcode the API endpoint URLs, as there's no way to use something like Url.Action to generate them automatically, any more. Regardless, it's a perfectly acceptable way to handle things.
You will probably at least want to add the base URL for the Web Api as an app setting in your Web.config, though. That way, you don't end up with hardcoded references to a particular domain strewn all about your app. That makes moving your Web Api to a different domain much easier, especially when talking about going from development to production.
It is also entirely possible to use a Web Api within your actual controller actions. You'll just need to use something like HttpClient to connect to it and issue requests.
the below process which i have followed while implementing single sign on
Decoupled Authorization server & Resource server
Got access-token using client_credentials from Authorization server
Problem:
i have used mvc 4 application for resource server and can't able to access views(resource) from resource server using mvc controllers with Authorize Attribute
used access-token generated by authorization server
also read the below question:
"I have an un-secured MVC 5/Web API 2 application. It accesses resources using a combination of MVC controllers, and ajax calls to the Web API endpoints.
Eventually I would like to move all resource access into a separate Resource Server. However, for the time being, I would like to get the application into production as a proof of concept for a line of business applications secured using the OAuth 2 framework.
I have configured users in IdentityServer, and added the application to AuthorizationServer using a code flow client. Based on the sample provided with the AS code, I am able to retrieve an access token in the application, add it to the request headers for Web API endpoint calls secured with the Scope attribute.
My questions is how can I utilize this same flow to secure the MVC controllers? I imagine it would entail setting up an OWIN middleware component which will set the authorization headers for each request based on a cookie which contains the token. Am I on the right path, or should I go in a different direction with this?"
please let me know how to access the mvc resource using owin middleware instead of web api.
I am developing an ASP.NET MVC web application. The application is consuming a REST API, but authentication for REST-full application is quite unclear for me.
As REST is stateless, do I have to implement two different Authentications with two different databases, one for client, and one for the REST service?
Or, do I have to send the login/password each time, to authenticate on the server?
Please give me some advice or tutorial on this.
You can authenticate a Web API using individual user accounts that are stored in a database.
In this case client should obtain access token first. And then include it to each request, that requires authorization, header:
Authorization: Bearer boQtj0SCGz2GFGz[...]
Good tutorial can be found HERE
Also authentication methods could be extended in Startup.Auth.cs with Cookies or some external authentication methods (Google, Facebook etc)
The stateless isn't a main problem in your situation, problem is that browser can only send GET or POST request in tradition way in tag form, so to send PUT or DELETE request you should use Ajax, the easiest way is to use JQuery library and config it to send user credentials in http header(between requests it can be store in cookies) in every request and use basic-authentication if you plan use own auth logic. I recommned you to look some SPA frameworks like angularjs
or emberjs
or backbonejs
to simplify your life from hardcode JavaScript . Also in future you can easy extend your auth by OAUTH 2.0.
I have two servers - web and app. The web server (IIS) serves only static files - HTML/CSS/JS. On executing the JS, the client gets the data from the app server (HTTP service using Web API, self hosted with OWIN). I need to bring in authentication so that my data as well as the content is restricted.
I can use SSL, I can pass username / password to the web api, have it authenticated and get back a token. I can pass this token for future web api requests. In my client app javascript (done using AngularJS), I can also maintain info whether the user is authenticated, what roles she has etc. (for user experience). But for security, I need to be able to ensure the html content requested (in the web server) is also having authentication and authorization done. How can I achieve this?
Should I change my app to make the web server call the app server internally rather than from the client? I can use MVC controllers or ASP.NET, but since I was using AngularJS, I thought it is not required, and is kind of a duplicate. Should I ditch pure .html files and move to .cshtml?
How is this done in the Angular + .NET world, when you data comes from a different server than your htmls?
We've been using JSONP with REST type api to do cross domain AJAX calls, but our Angular client code is within .cshtml files in a .NET project. Sounds like the simplest solution is to use the app server internally- I would go with that