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.
Related
I have multiple processes (some that are not under my control) that need to access an API that only allows me to create one OAuth 2.0 token at a time. If I create additional tokens, I run the risk of kicking users out of the application. What would you suggest on how to manage this?
I am thinking I will need to create a middle layer to manage the token and pass through the information to the API. This is fine, but even so, how do I make sure that I only ever have one active token at a time if there are multiple requests coming in per second to this middle layer? Would I not run the risk of one call creating a token because none exists (so it cannot be refreshed) at the same time another call is performing the same action?
Given the fact that there are multiple processes, the oauth endpoint is the spot where all of them meet. Seems like a logical spot to address the issue.
First of all, I would create an oAuth proxy (as you said), so all of processes use that to get access/refresh token. This proxy will be used for both getting original access/refresh tokens and handling refresh as well.
As for making access token being exactly one thing, I would use this logic:
initially, the proxy has no access token, so when multiple processes come to get one, the proxy will hold all of those threads and will request exactly one access/refresh tokens from the original oAuth server
since you control the proxy, you can synchronize threads to make sure they all wait for the access token to be available
at this point every process will have the same access token
I would make the proxy to understand when the access token get expired, so when a process asks for a token, and if the token is expired (but not before) then the proxy would refresh the token, cache it and return
the fact that the proxy won't request a new token till the old one expires; that guarantees that there will be no more than one access token available at the same time
I have a webpage(Angular), which authenticates the user, after login in(oAuth2), the user has an option to interact with the bot (Bot Framework v4 C#) as of now I had the bot Independent, hence had used the OAuthCard in the bot to authenticate the user.
Now I want to have a Single Sign-on. I am not sure how the user token will be passed from the webpage to the bot, I have two scenarios now sure which is the correct one:
1. Send the user token with every message, requires validation on every message, too much computation.
2. Send the token with a TTL, and handle the expiry.
But for now, I am not sure how to send the token from the Webpage to the C# App.
I did go through this, and as it says
"A third option, called Single Sign-On (SSO), is in development and is where the client UI takes the client’s user token for the client app and exchanges it for a different token that can be used with the same identity provider, but a different app/scopes. For now, it is possible to create a similar user experience using WebChat by using technique #1 above."
And the document seems a bit too sparse to understand how exactly it was done with technique #1
I agree, that blog post is quite confusing and I still have no clue what they're intending to eventually do for what they describe as the "SSO scenario". The major difference they describe there from simply handing the bot the token from the SPA is that they will do some sort of token exchange for a different set of scopes that the bot needs vs the SPA. This would certainly be useful, but, as of right now, it's "all talk" and I'm not aware of anything they've built to enable it.
Let me just address your two points real quick first..
Send the user token with every message, requires validation on every message, too much computation.
First off, I would venture to say that the majority of the web is built on token exchange at this point. Tokens need to be continually passed around, signatures validated and then checked for expiry. This is just the nature of authentication; I don't think this is a bot specific problem.
Send the token with a TTL, and handle the expiry.
Are you using JWTs? They have TTL built into them via the standard exp claim, so you shouldn't need to worry about inventing your own TTL. Yes, you do need to check for expiry.
Ok, that said, if you're concerned with the overhead of constantly passing the token to the bot, you can choose to send it once via a custom, "backchannel" event over the DirectLine connection. Your bot can then take this token, validate it once and associate it with the conversation state so that the client need not send it on every request. Keep in mind however, you will still need to continually validate the token has not expired.
This backchannel event and the handling of it would be completely proprietary (e.g. there is nothing in the box to do this for you today). Just like you would have an event from the client to the bot to send the token in, you can also have an event that goes from the bot to the client to tell it it needs a token from the client (e.g. first request, or refreshed one because of expiry).
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.
Note: This is not about coding, but about the approach itself.
I'm making a client for a website which uses OAuth 2.. Since this is my first time using oauth 2 I have some problems in understanding the approach. As I know until now:
I should send my access token with every request. To get this access token in the first time I send user to the website and after login I get an authorization code. Then I send this authorization code and my client_id and client_secret to get the access token and finish.
until here every thing is fine. But in the next application execution, I don't know what to do. I don't want to ask user to login every time. But how can I know my access token is still valid?
should I save my authorization code and request a new access token again?
I request a non-expiring access token, but to refresh the access token I should send some refresh_token? What is this? Should I send the old access token as this?
#Eugenio's answer is correct.
To answer your specific questions
But how can I know my access token is still valid?
The access token comes with an expiration time, usually one hour. The other way is to try to use it and catch the 401 status if it's expired.
should I save my authorization code and request a new access token again?
No. The authorization code can only be used once. You can either request a refresh token, save that, and then use that to get subsequent access tokens, or you can repeat the authorization process, which depending on the provider, may or may not require user involvement since the provider will know that the user has previously authorized your app.
I request a non-expiring access token, but to refresh the access token I should send some refresh_token?
There is no such thing as a non-expiring access token. You use a refresh token in order to obtain a new access token.
What is this [refresh token]?
It's a string that your app can pass to the provider to say "hey it's me again. Remember a while ago user xxxxx, granted me, application yyyy (client id), the authority to do aaaa and bbbb (scopes) on his behalf, even when he's not present. Well I'd like to do some now so please can I have an access token".
Should I send the old access token as this?
No. Once an access token has expired it has no use or significance at all.
The access_token you get from the authentication site is good to call their APIs, not your app. You should keep it if you need to call them back eventually in your app.
For example, if your users are authenticating with Facebook, the access_token you get will be good to call Facebook's endpoints.
OAuth2 is in essence an authorization protocol: the user is granting you permission to access his/her information on their behalf.
A commonly used, and useful side effect of this process is to treat these users as "authenticated" because, presumably, you can only get an access_token from a legitimate user.
It is then up to your site to establish a session with them. You would do this exactly as you would if you were authenticating the user yourself, likely after you successfully retrieved the access_token using the code. (or sometimes after retrieving the user profile from the Authorization Server, another common technique).
You can browse a sample that does this on the .NET platform here: https://docs.auth0.com/aspnet-tutorial (this is configured to work with our own OAuth server, but the principles are generic).
The code this sample relies on is available here: https://github.com/auth0/auth0-aspnet
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.