Why hello SOers. My question today is about authentication endpoints and the architecture surrounding them.
Most web frameworks and applications I've encountered seem to have a single URL or endpoint to deal with 'authentication' - e.g. processing authentication tokens such as usernames and passwords, and doing something with them.
It seems to me like this causes a lot of follow-on work, like for example if you hit an auth-required URL, the system needs to pass that URL to the authentication endpoint in order to redirect you back there after authentication and authorisation.
Why not simply listen for authentication tokens on EVERY URL endpoint? With a modern MVC framework utilising a PageController or FrontController pattern this should be simple.
Am I missing the downsides of such an approach? Do some frameworks already utilise such a system? Opine me!
Why not simply listen for authentication tokens on EVERY URL endpoint?
Ignoring the word end-pont for a moment, that's what the out-of-the-box Microsoft Forms based authentication does; in the config you specify the parts of the site you want to protect (like the "admin" folder, whatever), you can have as many of these as you like.
When the user hits anything covered by that (as long as IIS pipes it to the ASP.NET processor) they will need to be authenticated (if they aren't already).
I would imagine the ASP.NET MVC works in exactly the same way.
Not sure if that answers your question (?)
Related
I'm struggling with these concepts and having trouble finding good resources on the web.
We are looking for ways to switch out custom implementations tightly integrated into our application for standards based authentication and authorization.
Our scenario is as follows:
A simple web site (may be an app in the nearby future)
A user must log in or otherwise gain access (i.e. there's no "guest" content or other things you can do as a guest)
The site uses its own web services (REST and/or SOAP) on the backend, but it might use 3rd party web services or exposes its own services as 3rd party services for other applications
Authentication may very well be done by an external provider: Users carry a smartcard and we'd like to have one simple identity provider which reads the smartcard information and sends it back to my simple web site (so I know who the user is and what his role is for instance)
Other sites might use other methods of authentication (simple username/password for instance), so we might need a configurable Service Provider??
I'm currently looking at OAuth (2) to implement for authorizing use of our REST Services (is it also useful for SOAP?) to our web site, perhaps with a simple "Client Credentials Grant" type.
But for authentication, I'm still none the wiser. There is OpenID, but is it easy enough to build your own OpenID Identity Provider? There is Shibboleth, but it seems to have a steep learning curve for doing custom stuff. And I've looked at just building something from scratch based on the SAML Authentication Request Protocol with an HTTP Post binding. Are there any other options?
Please keep in mind that we want to be flexible with our authentication. For a certain site, we might want to do the smartcard thing, but for another maybe simple username/password login with LDAP.
If it's helpful still, I personally thought about doing it myself, then discovered a bunch of third parties. I compared (5/18/2015):
Auth0
AuthRocket
UserApp
DailyCred
Conclusion for me was Auth0, because while all the features are very similar, it felt the most legitimate, as in it's not a start-up that might disappear in a few months. Now, the reason that was super important for me was because login is a foundational requirement, so I need to believe as a customer that the Authentication as a Service will be up for as long as I will be.
Here's the full comparison story:
https://medium.com/#bsemaj/authentication-as-a-service-comparison-5-quick-lessons-for-b2b-businesses-e7587275824c
I've setup security in my RESTFUL WCF services using Custom Basic Authentification (thus desactivating the iis Basic Authentification and not using Windows Accounts Login at all; my service is hosted by iis) using the following link.
blog link
I understand the consumers have to implement a client to pass credentials in the request header.
It is 64bits based encoded and we can see credentials passing in firebug network tab while debugging (it is always the same string encoded <=> same credential .......)
So, in addition, to enforce security I will add SSL to encrypt the url :
https://myrestfulserviceurl.com/Method
Now the consumers ask me why we don't just put the login and password in the url request i.e
https: // myrestfulserviceurl.com/Method?login=XXX&password=YYY
(also combined with SSL)
Thus the change requires to add login and password as parameters in my Operation Contract and call a method for authentification in my method "Method".. etc etc
My question is :
What is the difference (both scenarii will use ssl) between Custom Basic Authentification (credentials in request header) & simply passing credentials in url in param ?
I mean : I'm just asking myself why I do bother to implement Basic Authentification. Passing credentials in url or in header look similar : it's passing stuff in the request. But talking in term of security, it looks the same ?
Basic Authentification looks not more secure excepted the 64bits based encoding.
Correct me if i'm wrong.
I am just looking a reason why implementing Custom Basic Authentification.
Any idea/advise?
Thanks
The main difference that comes to mind is to do with how visible the data is and how long it is likely to be retained.
For instance, assuming SSL is terminated at your application server, values in the get parameters are likely to be automatically logged to your file system (in request logs for instance). Having usernames and passwords in there is not ideal as it makes it much easier for them to be leaked.
If SSL is terminated at a loadbalancer or some similar proxy, then the usernames and passwords could be saved in request logs on servers you may not be thinking about and probably have less control over.
By contrast, the Authentication header is much less likely to be logged to places you're not expecting.
I thought about doind this myself and decided against it because i wanted the Restful URL's to focus only on the operations and keep security out of it, for example I might want to re-use the same code on a different application.
Also Im not sure but i think there could be a security implication concerning replay attacks, if someone obtained the link then they could execute it in any http client. If you used the authroisation attribute in the http header you could avoid this by putting an expiration on it. Also i think its better to hide this information from the html page body.
The dude who wrote this http://lbadri.wordpress.com/2012/07/30/anatomy-of-a-simple-web-token-swt/, which is taken from his book "Pro ASP.NET web Security". Gives a pretty decent example of creating a token which you could then use in the http header "Authorisation", like: Authorization: Basic d2FsaWRAGssSGZ21haWwuY29tOn236dhbGlk
I have a web service built with WebAPI that accepts JSON requests and responds accordingly. The core architecture is built but there isn't any authentication/authorization.
After a lot of googling and poking around sample projects, I'm not sure where to start. I've found a ton of material from 2008 and 2009 but not a whole lot of recent guides/workflows for WebAPI / single page apps. I think the workflow should be as follows:
Check to see if the user is logged in: How can this be done with javascript? Do I send a cookie to my webAPI? If so, do I send that cookie as a parameter in the body of the request?
Let the user log in / register: How is this data encrypted/decrypted? Surely I can't be sending passwords over the wire... is this where SSL comes in?
Provide them with access to what they have rights to access: I think I got this - I can just authorize in the controllers on a per-request basis.
Any info would be awesome.
Basically you need a token based authentication or authorization.
If you are referring to the ASP.NET WebAPI, the following project will be a great place to start:
http://thinktecture.github.com/Thinktecture.IdentityModel.45/
Even if you are not using ASP.NET WebAPI, the following video is a great introduction on how to provide authentication/authorization on RESTful web services:
http://vimeo.com/43603474
To answer some of your questions:
Check to see if the user is logged in: How can this be done with javascript? Do I send a cookie to my webAPI? If so, do I send that cookie as a parameter in the body of the request?
You can use a cookie but I normally use the header in order to avoid common XSRF attacks. Cookies are automatically included whenever a http request is sent from the browser.
is this where SSL comes in?
Yes. If you are going to go ahead with the token based approach, you can use a separate server (Identity Server) to do the authentication for you.
JavaScript clients are unique. Do you have the Web API and the page serving up JavaScript in the same domain? If not, you have same origin policy restrictions. If you have the same Web application hosting the web pages and Web API, you can use forms Authn. In that case, you don't need to send the cookie containing the authentication ticket yourself from JavaScript. Browsers do that for you and that is the cause of XSRF problem. You have to be careful about JavaScript sending credentials that the end user is not supposed to know. If JavaScript knows something, any intelligent end user can get to that knowledge. OAuth 2.0 implicit grant could be a good choice. The end user enters the credentials (password) in the authorization server which issues an access token. JavaScript gets the token and presents it to the web API but it will never have access to the credentials.
My company is re-writing its e-commerce site as a single page application using the new Web API / SPA features in MVC 4. We're not sure about the best way how to handle authentication.
Specific questions:
How do we handle both encrypted and non-encrypted communication? Clearly, we need to use HTTPS for the login, account, and checkout AJAX, but we'd like to use HTTP for browsing the catalog in order to avoid expensive SSL handshakes that would slow the whole site down. Is this even possible for a SPA, or are we stuck with HTTPS for everything?
What sort of authentication should we use? Primarily our site will be accessed from a web browser, so cookies may be fine. But down the road, we may want to make a custom iPhone app. Is Basic Authentication, OpenId, or OAUTH preferable? If so, why?
If we go with Forms Auth and cookies, will the redirect issue be fixed for the release of MVC 4, or do I have to use the haack?
If we go with Basic Authentication, how do you do persistent sessions, so that users don't have to log in every time they go to the page again.
Which authentication methods are well supported by ASP.NET MVC 4. It'd be ideal not to have to write a lot of specialized code.
Thanks in advance
1. How do we handle both encrypted and non-encrypted communication? Are we stuck with one protocol, https, with a spa?
You are not stuck with one protocol. With a spa you can use ajax to communicate over http or https, whichever one you choose at any given time. I would use https for anytime your are sending sensitive information like a persons name or their birthdate or login credentials.
Once a user logins to your site over https then your server can set a forms authentication cookie for that user. This cookie should be an encrypted value that ties their session to the server. You must be aware that if the rest of your site is using http then you have the risk of this cookie being passed over the wire in plain text. Even though the contents of the cookie can be encrypted, using an encryption algorithm of your choosing, a malicious person can steal this cookie and jack your user's session.
This might not be a big deal to you though if they are only allowed to browse the site and create a shopping cart. Once the user is ready to checkout then you should re-authenticate the user, over https, as a sort of double check to make sure they are not a malicious user. Amazon does this.
2. What sort of authentication should we use?
Well, that's all a matter of what features do you want your site to have.
OAuth is for exposing webservices which you can allow other sites to call with delegated access. What this means is that if you have a user who wants another site (site x) to be able to access features on your site for their profile. The site x can redirect the user to an oauth endpoint on your site which will authenticate the user. Your oauth endpoint will ask the user if its okay that certain features are shared with site x and if the user agrees a token will be generated. The user passes this token to site x where site x will make server to server calls to your site. Site x will present the token in the calls so the calls to your services will be a delegated access call. OAuth is a way of provisioning other sites to make delegated access to your services. I hope i was able to explain that clearly.. I'm not always good at this.
OpenID is not a very secure way of handling authentication its more of a convenience so that users don't have to be hassled with registering an account with your site. Because OpenID is completely open you are trusting another provider to validate your users. If the third party provider's user store is compromised then your users are compromised also. It's an example of a voucher system where you are basically saying I will trust who you say you are, if you can have an OpenID provider vouch for you.
Another solution is WS-Federation. WS-Federation is if you have multiple sites and you want to have 1 authentication provider that you trust. This authentication provider can be yours and basically all your sites say if you want access to my site then you have to first be authenticated with my authentication provider. This authentication provider can live on a seperate domain and can choose any authentication mechanism it chooses. You are trusting that this auth provider will do its best job to manage your users accounts.
WS-Federation can be overkill though if you only want authentication on your site and don't have multiple sites. In that case I would just recommend doing Forms Authentication and this should be simple enough to do. There are lots of examples of how to do this and microsoft provides many solutions for how to do this. You should look into creating a custom membership provider.
Once a user has been authenticated with your site you should create a forms authentication cookie. This cookie ties the user to their session on the server. This applies to all the scenarios listed above. MVC 4 supports all the scenarios listed above also.
Thanks, and feel free to ask more questions if I wasn't clear enough.
** EDIT 12/1/2017 **
Coming back to this question years later I have learned that relying on cookies for REST based APIs is not a good idea. You don't want to create a session on your web application because it makes your app harder to scale. So, if you need authentication then use HTTPS with some form of authentication (BASIC, DIGEST, Token Based, etc..). So, your SPA client appl will set the Authorization header on every http request and then your web server app will re-authenticate every request.
The main downside of using ASP.NET's form based security is that it assumes you're want a 401 web page when your authentication fails (useless when you're doing an AJAX call) and it's really designed around doing redirects which kind breaks the whole SPA pattern. You can hack around it but it's not designed for the purpose you're using it.
This toolkit may provide an alternative to ASP.NET'as form model.
Not yet sure how mature it is ...
http://www.fluentsecurity.net
Feedback welcome.
I just started working with webapi myself so don't consider my answer authorative. I'm not a security expert though I should be. I ran into the same questions as you did and found, as you did, that there is no authorative answer though - within mvc webapi at any rate. Looking at other webapi specs may give you some inspiration.
The simplest way I came across was of course using SSL. That let's you get away with sending credentials in clear text in the header. Doesn't break rest.
My api will employ SSL all the way but I wanted to double up anyway. So I'm sending an encrypted key in the querystring for all my requests. Pretty much the way cookieless authentication works for a non api asp site, but mvc doesn't play with it so I've rolled my own solution.
On a mobile site, the user would log in, be redirected, to the app with the encrypted key encoded into the js. So he'll initially have a cookiebased auth for the site, and be responsible for it's protection, password saving etc.
Another api consumer would get a more permanent "secret" from a dev site yet to be made and use that to check out a key.
Normally mvc authentication is stateless, meaning the ticket is never invalidated server side. If you controll the client you can just ignore invalidate cookie requests if the server logs you out, and just keep on reusing the ticket. Eventuelly you might want to keep track of your tickets server side, but it's not stateless, doubt if it's restfull, and by consequence scalability taket a hit. But authentication is pretty important so...
I'm building Pylons-based web application with RESTful API, which currently lacks any authentication. So I'm going to implement that and in order to avoid all the trouble and caution with storing user passwords, I'd like to use OpenID for authentication. What would be the best way to do this? Are these two things compatible? Are there existing REST APIs that use OpenID that I can take inspiration from?
I've now spent some time researching the options and would like to summarize the findings.
First, a little bit more context -- I develop and control both the service and API consumer. Consumer is Flash-based app that is served from the same host the API is now and is supposed to be used in browser. No third party clients in sight yet.
So the question can be divided in two parts,
how do I do the OpenID authentication via API
how do I maintain the "authenticated" state in subsequent requests
For first part, OpenID authentication almost always includes interactive steps. During the authentication process there will most likely be a step where user is in OpenID provider's web page, signing in and pressing some "I agree" button. So API cannot and shouldn't handle this transparently (no "tell me your OpenID provider and password and I'll do the rest"). Best it can do is pass forth and back HTTP links that client has to open and follow instructions.
Maintaining "authenticated" state
REST APIs should be stateless, each request should include all the information needed to handle it, right? It wouldn't make any sense to authenticate against OpenID provider for each request, so some kind of session is neccessary. Some of the options for communicating session key (or "access token" or username/password) are:
HTTPS + BASIC authentication ("Authorization: Basic ..." header in each request)
Signing requests Amazon-style ("Authorization: AWS ... " header in each request)
OAuth: acquire Access Token, include that and a bunch of other parameters in each request
Cookie that stores session key ("Cookie: ... " header in each request)
Signed cookie that stores session information in the cookie itself
There's just one API consumer right now, so I chose to go for simplest thing that could possibly work -- cookies. They are super-easy to use in Pylons, with help of Beaker. They also "just work" in the Flash app -- since it runs inside browser, browser will include relevant cookies in the requests that Flash app makes -- the app doesn't need to be changed at all with respect to that. Here's one StackOverflow question that also advocates using cookies: RESTful authentication for web applications
Beaker also has nice feature of cookie-only sessions where all session data is contained in the cookie itself. I guess this is about as stateless as it gets. There is no session store on server. Cookies are signed and optionally encrypted to avoid tampering with them in client side. The drawback is that cookie gets a bit bigger, since it now needs to store more than just session key. By removing some stuff I didn't really need in the session (leftovers from OpenID authentication) I got the cookie size down to about 200 bytes.
OAuth is a better fit for API usage. Here's an example of OAuth in use in Python: oauth-python-twitter. Leah Culver's python-oauth library is the canonical implementation of OAuth in Python, but python-oauth2 is a recent contender that is getting some buzz. As for inspiration, django-piston has support for using OAuth to do auth when creating RESTful APIs for Django, though the documentation isn't as nice as I'd like for that particular topic.
If you build API, you could check OAuth protocol. It's complementary to OpenID.