I have been working on a RESTful webservice for an android native application to consume. I choose ASP .NET WEB API. WEB API makes it very easy to create those HTTP methods in controllers, and converting our response objects into json/xml... Its simply awesome!
Now comes user authentication and those session handling parts. First I thought it will be easier to implement sessions in my RESTful service. But really frustrated with the configurations for enabling sessions in WEB API, and making the android native to handle those session ids.
First, Android sends login request to WEB API
WEB API checks authentications, and responses with a sessionid in response header
Now Android native reads the response header->fetches ASPNET_sessionId ->keeps in its memory
Further requests from android will have to set this ASPNET_sessionId in request header
Do you think this is a proper way?
And now I have another client. A hybrid app in Mobile jquery. Now facing following problems:
Access-origin policy: So I set Access-Control-Allow-Origin to * in response header. And it solved.
Now I need to set session id in jquery ajax post request. And found its not possible to set headers for jquery ajax when calling a cross domain service.
How can I manage session for my hybrid app?
Also What are the things taken care of while creating a web service that has to be consumed from different client applications?
After a lot of research I have come with following points:
REST is stateless. So why do we need to play with session? there by giving it a stateful life?
No need for enabling session state. When a user logins into
application we creates a unique id for user in database. Further
requests from the user will send this unique id as a part of message
body. Server checks this unique id every time for identifying user.
Cross-domain issue in Hybrid app
When converting app to hybrid with cordova we found that cross domain
issue is not occuring. It is believed that cordova converts jquery
ajax requests to native requests calls from android. jsonp also found to be a good solution.
Related
I have a website written in ASP.NET WebForms, which accesses web services that are written in ASP.NET WebAPI. For security, I closed port 8079 (web services) so that web services could only be accessed via the website, but that it would not be possible to request web services directly from the Internet. When I request a page on a website, through the Fiddler program, I see a request for a website, but I don’t see a request from a website for web services. Everything works well. But now I have made another website written in AngularJS and I want this website to also access my closed web services. Is this possible through AngularJS? Below is the request code for web services via ASP.NET website.
HttpResponseMessage response =
client.GetAsync("http://localhost:8079/api/values/5").Result;
if (response.IsSuccessStatusCode)
{
Task<string> data = response.Content.ReadAsStringAsync();
result += data.Result;
}
As a result, the site(AngularJS) and ASP.Net MVC Web Application should be available on the Internet, and web services (ASP.NET WebAPI) should not be available on the Internet.
Currently, the client accesses the web services directly, but it’s necessary to make the client access the web server and the web server access the web services
Even if you create another ASP.NET app (a kind of 'facade') that handles requests from the client, and invokes web services internally, this alone won't solve the problem:
If the facade accepts requests from any client and just sends them to the web services, it is not different from exposing the web services directly to the internet.
As #Andrei Dragotoniu pointed out, you have to secure your services by only accepting requests from authorized clients.
How to authorize access to web services
A common way of securing access to web services is JSON Web Token (JWT). The token contains encrypted claims that explain the identity (and maybe other aspects) of the client. Typically it works as follows:
A new token is generated on the server upon successful authentication of the client. The authentication can be either manual (a login form), or automatic (for example, with OAuth).
Once the token is generated, it is returned to the client. The client then starts attaching the token as an HTTP header to every request it sends to the web services. On every request, the web services validate the attached token.
This blogpost provides more information and examples of using JWT in C#.
API Gateways
The requirement of limiting access to web services to an internal network is not uncommon. A typical solution here is API Gateway.
(from Wikipedia) Gateway: a server that acts as an API front-end, receives API requests, enforces throttling and security policies, passes requests to the back-end service and then passes the response back to the requester. A gateway often includes a transformation engine to orchestrate and modify the requests and responses on the fly. A gateway can also provide functionality such as collecting analytics data and providing caching. The gateway can provide functionality to support authentication, authorization, security, audit and regulatory compliance.
More on API Gateways in this article. One of the most popular API Gateways is Kong.
Even if you deploy your web service in intranet, you cannot consume the web service from client browser (Angular or JS Applications).
One possible solution could be,
Deploy the web service in intranet web server.
Create a proxy web service in the edge server (they are both intranet & internet facing). Proxy web service should just expose the required methods by obscuring the original web methods.
Consume proxy web service from client-side applications.
Otherwise, client-side applications can never consume the intranet web services.
Optionally, if you create NodeJS, ASP.Net based web applications, it can be deployed on edge web servers that can talk to intranet web services and users (living in the internet) cannot access web services directly.
UPDATE:
Moreover, based on your code above, it looks like you are trying to consume web service from .Net Runtime Managed Code (ASP.Net MVC). Well, in that case, AngularJS will ajax to your controller-action. Then controller, in the edge server, can talk to any intranet web service. AngularJS need not talk to Web Service. It is straight-forward now.
"When I request a page on a website, through the Fiddler program, I see a request for a website, but I don’t see a request from a website for web services"
That statement is true in a very limited context, but the reality is much bigger than that.
The requests from a website to its own API can easily be seen by using browser tools for example ... hit F12 in any browser and look under the Network tab, this is something anyone can do to see what a website ( any website ) is doing.
You need to protect your API somehow. You can use something like OAuth2 or you could do it at server level. You can lock down a server to only accept connections from your website's IP address for example. You can also make it so that the server the API is on is completely locked down. You can lock down the API.
You just need to realize that you do have a security issue if you don't do something. The tech stack you use is irrelevant for this.
I am developing a project in Angular 4.0 and using c#.net web API as back-end.
Problem is, When I am running my application through browser, I am able to see web service call (get/post) through "Postman Interceptor". Which is not good for security. Is there any way to secure my webAPI call so that it will not be visible in "Postmatser" or fiddler like tool?
Is there any way to secure my webAPI call so that it will not be visible in [Postman or Fiddler]?
No. You're issuing requests from the browser. This means they will come from the visitor's pc, and everything that happens there can be intercepted by them.
You don't need obscurity, you need authentication.
I am working on combination of Web API application and desktop client program (WPF). I am using Microsoft.AspNet.WebApi.Client for a client-server HTTP communication and now I want to use authorization / authentication system of the server application to authorize user of the client program.
Point is, I want to use (=start with) the same HttpClient class, I would like to use ASP.NET Identity library on server side - call controller with credentials in HTTP header, receive actual token from server, keep it and than use it for authentication in other controllers where it is required.
I know the theory, some basic steps, but I have not found any useful and actual resource with a simple examples or tutorial how to do it well. Does anyone know about good resource to learn, how to do that?
Thanks a lot.
I have a server-client project written in c#.
I want to change the client side to a web client so we can open it with the browser. So I decided to make a WCF rest service that will replace the server side. The binding that I am using for the service is webHttpBinding.
My problem is with the behavior of the service. The service data (vars etc..) is initialize after every call. If i add the [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
it doesn't change anything. If I use [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)], it works but I guess that the service instance will be the same for every client.
I have a simple html web page that get a username and password from the client and post it to the service. The service check the Login info with the user database and response. My problem is that i can't save the user status as logged in or not because after every post/get method the service is reset.
what should I do?
This is a pretty standard issue you have to deal with when trying to maintain a session over HTTP, which is what webHttpBinding is using. Even if you try to force it to have a session, it won't. RESTful services don't work that way.
A high level overview of what you have to do is have the service create a token it gives the client upon initial authentication (probably to be stored in a cookie), which the client will then send back with each request. The service can then use that token to check if the client is logged into a particular account with each request. You probably want to make tokens expire after a certain duration (might be 1 month, 1 week, 1 day, 10 minutes, depending on your application).
You can find some more information here:
RESTful Authentication
SPA best practices for authentication and session management
Authentication, Authorization and Session Management in Traditional Web Apps and APIs
I have a Windows Service running a Web API hosted as a OWIN middleware - the server. The API uses application cookie authentication and validates users against a database, using OWINs identity model. Now I would like to authenticate a user who accesses the API through a standard MVC web application (the client), but I'm unsure how to achieve this, e.g. after I received a response along with the cookie from the API, where do I have to store it inside the MVC application so that the cookie will be automatically sent along with further API calls.
You won't need to. Cookies are stored by the client's browser, and are sent to the web server with every request on the same domain name. Each subdomain will have its own sandbox for cookies. The main domain's cookies can be accessed by all subdomains.
MVC application will store it in the users browser the cookie. If you need to find an alternate way to achieve it, why not try localstorage. You can then send the authorization token with every request header using your Ajax calls. If you are interested in an Angular Application, here is an excellent tutorial that should help clarify a lot of question.