I have a API mobile service that handles users' login and verification. If a user is verified then it produces an authentication token. On my end I have a Web client that receives that token and uses it to call different Api controllers. How should I go about keeping a user logged in status constant?
Can I store the token on a cookie? would it be exposed to abuse if I do so? would a session work better? What is the best way to handle this issue? Sorry for the noob question, but I have never done this type of setup before.
The token can be stored relatively securely on the client as a cookie. Here's an example using Forms Authentication. It can be made even more secure by requiring SSL.
You can also consider using HTML 5 local storage like this:
http://www.princesspolymath.com/princess_polymath/?p=396
...which can be more efficient, as you manually use the token when making AJAX calls that require it instead of sending the cookie on every single request.
Related
I'm creating a WebAPI based SaaS application. This WebAPI can be used alone without the need for a user interface, requires a basic authentication sent with every request made to the WebAPI and returns some objects when the methods are called and authenticated.
Now I'm facing a big problem: I'm creating a WebApp in MVC (but it could be any language) and I can't figure out how to call my WebAPI endpoint without the need to keep username and password in order to authenticate the WebAPI request every time I call a method.
What are the best practices in this particular case?
I can't seem to find any suitable solutions...
So far I have tried to create a custom cookie with the help of a custom implementation of the HttpContext.Response.Cookies.Add method, where I store in the userData of the Cookie the pair of username and password encrypted. In this way I can call the WebAPI methods specifying each time the BasicAuthenticationCredentials with the correct username and password, but this seems to me a very unmaintainable way to do the job in the long run.
I also wanted to try the OAuth2 way, but I can't find a well written guide on how to implement an authentication server based on a custom user table from SQL Server (and the first five pages of the Google result list didn't help me, they did actually make me even more confused about this topic, the whole OWIN and Katana thing...).
I can provide further information in case someone is willing to help me out.
Thanks in advance,
Stefano.
Here's a good tutorial about how to implement your own OAuth2 server:
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
The main idea behind using OAuth is that you'll only need a username and password for your first request, and after that, you'll get an access token that will be used to get access to the API. This access token will have a lifetime, and once it has expired, the user will need to request a new access token (either by sending the user credentials again, or by using a refresh token that will be used as a credentials substitute).
The nice part behind this approach is that since the access tokens have a lifetime, even if one of those tokens gets compromised, you can just revoke it (or wait until it expires, for example, you can create tokens that will be renewed every 5 minutes or even less. It's up to you), the client will automatically ask for a new one, and that will be the end of the story. On the other hand, if you were always receiving the user credentials and those credentials got compromised, the user will need to change them and the risk will be there until the user finally changes his credentials (and here's a manual process where the user needs to be aware about this problem, while the OAuth approach is just refreshing those tokens all the time).
Also, remember to keep all the communication over HTTPS, since the tokens are sensitive information, and you don't want an eavesdropper getting the access token or even worse, the refresh token by just intercepting the communication. If he's able to do something like this, then even tokens refreshing every minute will be a useless approach against someone getting every token that you send.
I am building a reactjs website that will communicate with asp.net web api 2 to save and retreive data.
but I am not sure how to do this.
I know to accomplish this on a high level it would be something like
User comes to my site and hits signup/log
Chooses which provider then want to use(google, facebook and etc). I am only want to support external providers(ie I don't want to have to deal with usernames/pwds)
User it sent to authenticated part of site
User clicks "add course" that data send via ajax to webapi with some sort of token to prove they have access to these methods.
I am not sure how to implement this problems I see is
Reactjs I guess is handling the authentication part? then once they been authenticated it would have to be saved in my db via webapi so it knows about this new user?
Reactjs would have to block users from going to secure pages till they are authenticated
Web api would have to generate a token for the user for that session so they can access the web api(I want to stop people from consuming my api).
Is there some simple example out there how to achieve this?
Reactjs I guess is handling the authentication part? then once they been authenticated it would have to be saved in my db via webapi so it knows about this new user
Better use some third party auth library here like PassportJS that does the auth for you using strategies like Passport-Facebook. This will give you an Oauth access token from Facebook upon authentication. You can now save this token in your cookies (or localStorage), take a look at the security considerations.
Should you store it in a DB? Here are some arguments about it.
Reactjs would have to block users from going to secure pages till they are authenticated
This can be done by checking if they have a valid token.
Web api would have to generate a token for the user for that session so they can access the web api(I want to stop people from consuming my api).
This can be easily achieved by using JSON Web Tokens. Note that you will have to store the JWT in your client side locally, along side your FB-Google oauth tokens (or you can relegate that to a single API by storing them in DB?. Its a design choice, I would prefer to store them separately and save a lot of hassle).
I looked everywhere for an answer about securing my webApi but always i'm pointed to OAuth or openID, but i don't want the user to login or authenticate. This is my problem:
I have a webapi which is called via Javascript to get the data in Json. This data is used in the Html of that page. (deployed on Azure)
Now i don't want someone else to get that data via Javascript or with a simple GET request. Only my html page is allowed to do so.
I'm looking for something to secure my Webapi to be only consumed by the applications i want. If i look to the OAuth and Azure stuff, people always have to login, but i want this page to be public, but only the webapi needs to be secure.
I can't check on IP, because the call is done at client side in the browser.
It is not possible to authenticate and thus secure the API to be used by a specific client (run entirely in the browser - like SPAs) app. You cannot protect the data the app sends to the API. (see for more details Protecting REST API behind SPA against data thiefs)
You could build some modules server side and then use some token based server to server communication if you do not want to introduce users and end user authentication.
Of course it is also a question of how you interpret security.
If it is just that you do not want other web apps to use the data -
CORS policies will do the job. It is unlikely that there will be more
than some isolated cases of users using a browser other than the
popular once which respect CORS.
If it is you do not want data to be mass downloaded you could
implement some client filtering based on IP. This could even be done
on the networking layer so the API do not need to be modified in any
way.
As a suggestion, you can have it secured making sure the request has some headers defined by you. For example, you can set an Authorization header with a token that only you know. You can for example, create a token based on a key that you and the webapi share, encrypt it with the time you are calling the api. The web api receives the request and:
1 - Check if the request has the token it requires;
2 - if it does, it creates a token the same way your page did;
3 - matches its token with the requests token;
If you are calling the webapi via javascript, the method may be exposed. However, it's one idea
Take a look to CORS (Cross Origin Resource Sharing), it may be your solution.
In synthesis you can allow requests to the Api only from some specific websites. Most, nearly all browsers, support it.
This is how you enable and configure it in Web Api 2.
I have an ASP MVC4 web site. Originally, most of the content was served via controllers as one would expect. I have moved the data storage from SQL Server to MongoDB. I have also added a lot of ajax to update data client side, without a full refresh. This is working fine, but my controllers now have lots of methods that take json and return json. I was able to build a Node.js server that hits the database and exposes exactly the same functionality, without lots of going to and from C#.
My javascript client-side is now calling a Node.js REST API, this works great. My 'secure' code (like adding a new user) hits the same REST API from the server side.
My question is this: How can I handle security properly with this? I have three scenarios:
GET api/messages: No need for security, I want to expose my site's messages to anyone who is interested via a Json REST API.
GET api/my/messages: I need to allow access to this only if the user is logged in (it gets the user's messages).
POST api/users: This is a function that should only be called from the server, and nothing else should be able to use it.
As the user is already logging in to my ASP website, how can I use their logged in credentials to authenticate them with my REST service? While the user is logged in, the pages client side will hit it regularly for updates.
Is there any sensible/standard way to do this? The core idea is that the client side code uses a REST API that is at least partially open to the public, and that in fact that API offers all of my business logic - only parts of it (like creating a user) are locked down to super-admins only.
Thanks in advance!
Create two authentication middleware handlers. One you add to all your "my" routes and another which you add to your POST routes.
The "my" authenticator takes the asp.net auth cookie that is present in the request and makes a http call to your asp.net mvc site with it.
You'll need an action which either returns a 401 if the cookie is invalid otherwise it returns some info about that user's permissions perhaps.
If the request into node doesn't have a cookie, return a 401 again.
In addition, to prevent excessive calls to your mvc site to check the cookie, you could use the cookiesession middleware to set a cookie on the client with a flag of authenticated. That will result in 2 cookies for your client, but that shouldn't be an issue. Just make the node one expire before the aspx one.
The POST authenticator middleware can use any shared secret you like between your node and mvc server. e.g. a special header in the request.
If the user is required to login you can use [Authorize] on your controller actions. Autorization will be handled like any other webrequest.
Furthermore you might consider to add a key to your api requests which you can provide in the initial page load. A autorized user will have a GUID which he will sent with the api call. You can check if this key was issued by your app to a valid user.
As you said all the secure calls already go through your MVC server code which in turn calls the Node.js code, am I right? Basically you need a way to block calls to this Node.js from other clients that are not your MVC code.
Thinking out loud, these are the ideas that pop into my mind:
Use SSL only between MVC and Node. You can set up client and server certificates so that the Node code will only respond after authentication (I don't know how Node handles SSL so you will need some documentation here
If you want, the Node server could also check the call origin and so you can filter based on IP and only allow IPs where your MVC code is sitting
Use an encrypted authentication token on the secure methods on the Node code. Again I'm not really a Node expert but I can imagine it has ways of decrypting a token, or you can simply base it on a random number with a common seed... If noone has access to your server code ideally noone should be able to guess this token. Again, SSL will help against traffic sniffing
I am quite sure that people will come up with other ideas. For me, the most basic thing is anyway ensure that the secure methods are only accessible through an SSL connection and on this connection you can exchange all the info (token, passwords, etc.) you desire.
We're looking into doing machine-based authentication, allow any user on particular machines to access our .Net site. The list of machines will change but are all on an internal network. Their IP addresses are assumed to not be static.
To make it more manageable we'd like to be able to restrict access to an Active Directory computer group.
I can manage the AD querying, my question is where is the best place to pull out the machine name and authenticate the entire session?
I looked into creating a new HttpModule but it seems I'll have to authenticate every request. Authenticating every request doesn't seem ideal if an AD query is involved.
The web is stateless, so every request is always authenticated no matter what technology you're using. However, the trick to not hammering AD is using a session http cookie. You would set this cookie on the first request and check for it on subsequent requests. You would need some kind of cryptographic protection on the cookie, but thankfully this is ready-rolled in ASP.NET. I'd say you could leverage the Forms Authentication infrastructure to set and validate a cookie - you would just offload the initial authentication to AD instead of reading from a posted form.
Here's a great place to start:
Understanding the Forms Authentication Ticket and Cookie
http://support.microsoft.com/kb/910443
You don't need to authenticate every request. Authenticate the first request with your HttpModule, and either add the requestor to the session, or cache the credentials for a short period of time.