If I am designing a social media website along the vein of Facebook/Twitter where users will be able to browse other peoples profiles, create public posts that appear on other users activity streams etc, and I want to design this using RESTful WCF services on the server end, with ASP MVC web on the front end, how is authentication managed? As there is no session state, every request the user makes will effectively need to be authenticated to confirm who is logged in and making each request. Eg "Search profiles", "View profile", "Update your own profile", "Upload new photo to your profile", "Post public message", "Reply to public message" are all actions the user will need to be able to do.
I assume something must need to be managed in the clients browser if the server holds no state, but how do you protect against spoofing, multiple user computers etc?
secondly, how is session lifetime managed with REST in this instance, ie if you want a user to be forced to reauthenticate out after 10 minutes of no activity, how would that be achieved?
The best way to do this is using OAuth.
https://developers.google.com/analytics/devguides/config/mgmt/v3/mgmtAuthorization
http://msdn.microsoft.com/en-us/library/dn277356.aspx
Basically once a login call is made you will have an authentication token returned that is used for all subsequent requests. All API calls will call to an authentication API to ensure the token is valid. You can expire this token at the authentication api after a set time if required.
To protect against spoofing, all calls should be made over https.
An advantage of implementing OAuth is then you can move the authentication to another provider, say google or facebook, so you do not even have to store user credentials on your site at all.
Related
We have a company building a web application for us and they want to authenticate using our existing website. I have written a login form that authenticates the user and needs to send back a token they can use for all future calls. At the moment I'm setting a cookie before redirecting back to their web app but I'm not sure if this is the way to go. Also, I need to test what I have built but not sure how to redirect to a login page and wait for that token response.
Token based authentication is stateless. You are not storing any information about your user on the server or in a session.
This concept alone takes care of many of the problems with having to store information on the server.
Although this implementation can vary, the gist of it is as follows:
User Requests Access with Username / Password
Application validates credentials
Application provides a signed token to the client
Client stores that token and sends it along with every request
Server verifies token and responds with data
More info here The Ins and Outs of Token Based Authentication
Here's an infographic to explain the process:
We currently have our identity server setup with Sustainsys/Saml2 extensions to allows 3 party clients to login to our product via sso, where the request is initiated by the client hitting our login page to start the request.
We now have a customer you want to put a link into there own software to start the process, creating a ldp initiated request.
My question is how do i go about implementing this using identity server and the Saml2AuthExtensions. I've had a look and i cant see anything extra that might allow this through. Does it just work out of the box, or do i need to setup something else?
Cheers
The SAML2 standard supports "Idp initiated sign on", which can be enabled in the Sustainsys.Saml2 library with the AllowUnsolicitedAuthnResponse flag on the Idp. It is however a bad idea, because the idp initiated flow is by design vulnerable to session pinning attacks. I have seen people make IdentityServer work with idp initiated sign on, but it's awkward, because IdentityServer is not built to support it.
It's much better to use the OIDC way. Have the customer put a link directly to the client application (I assume that the end goal is a client to IdentityServer, using OIDC). Then create an endpoint on the client that initiates an OIDC sign on to IdSrv, with an amr value indicating to IdSrv that Saml2 should be used for authentication. That can give a solution where the user clicks a link, goes to the client, is redirect to IdSrv, is redirected to the Saml2 Idp where they are automatically signed in (using e.g. Windows Auth or an existing session). Then they are automatically redirected back to IdSrv which redirects back to the target application.
From the users' perspective they have a link that will automatically log them in to the application.
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).
We have an ASP.NET/MVC website that's using FormsAuthentication. As is usual, when the user tries to access a page, and doesn't have a valid FormsAuthentication cookie, IIS redirects him to the login view. When the user does a HttpPost to the login controller, our controller action makes a call to our WebApi webservice, which validates username, password, and customerid against a Sql Server database. If the authentication passes, the controller action sets a FormsAuthentication cookie, and redirects to the page the user had asked for.
Now sales is making noises about "Single Sign-On", though I'm not clear exactly what they mean by that. From what I've read, in the Microsoft World this usually means accessing MS's Active Directory Federation Services.
At this point I have almost no idea how this would work, but before I dig into this too deeply, would it be possible to put the authentication code within the WebApi webservice, where we could choose to validate against the Sql Server database, or against whichever ADFS server was appropriate for the specified customer?
Our problem is that we have I don't know how many thousands of users, working for some hundreds of customers. Many customers will not have ADFS running, and those who do will each have their own ADFS server.
Most of what I see with respect to Single Sign-On seems to involve doing browser redirection to the ADFS server, then redirection back, and looks to be avoiding login at all, if you're already logged in. I don't think we can do that, in our case. We can't know which ADFS server to redirect to, until we hit the database.
So, the question - is it possible to do ADFS authentication entirely from C# code in our WebAPI web service?
(One possible complication - the website itself has zero access to any database. The sole configuration setting in its web.config is the base URL of the webservice. Whatever authentication happens has to happen in the webservice, not in the website.)
First of all, "Single Sign-On" (SSO) is not limited to ADFS. It simply means that you type your credentials only once, and then all systems you access automatically "recognize" you; all subsequent authorizations request are transparent. For instance, if you have several web sites using Windows Authentication in your company Intranet (same AD domain), you have SSO: you authenticate once when you log in to your computer, and then your web browser authenticates automatically to these web sites using NTLM or Kerberos. No ADFS in this case.
What ADFS (and "Federation" more generally) allows, is SSO accross security boundaries. In Windows world, a security zone is typically created by an Active Directory forest; everything within this forest is accessible using SSO provided by Windows authentication. But as soon as you leave this zone (SaaS application, web site in another company network), you need another authentication protocol to perform SSO, and these protocols are implemented in ADFS.
Then about your particular problem:
What you could do is instead of using FormsAuth, you use AdfsAuth. When a unknown user accesses a page, he would be redirected to ADFS for authentication (using browser redirects as you correctly mention). To know which ADFS server should authenticate your user, you need a way to differentiate them indeed: a list of IP range per customer? a different URL per customer? If you don't have something like this, then the only way is to show them a list of choices such as: "I work for CompanyA", "I work for CompanyB", "I work for CompanyC", "I don't work for any of these companies and want to authenticate using FormsAuth."
In this case, what your WebApi web service has to do is: if I know which ADFS server to use, redirect the user there. Otherwise authenticate the user as usual using the database.
When you use AdfsAuth for a customer, your database is useless. You can delete all credentials related to this customer.
do ADFS authentication entirely from C# code in our WebAPI
Well it's possible to "re-implement" ADFS in your service, but you won't get SSO if you do that. When you use federation, your redirect the user to the ADFS server of his company. This ADFS server is in the same domain as his computer, so the user gets SSO here. Once again, your users can't get SSO if you authenticate them yourself, because your users are not in the same security zone as your site.
When authenticating to multiple identity providers, it is typical redirect to your own STS. So, in this case, you would have www.yourapp.com redirecting to sts.yourapp.com, which redirects to sts.somecustomer.com.
The specific tools to enable such a dataflow is the home realm parameter (whr), and the AD FS Powershell API (to allow IDP maintenance).
Your RP-STS acts as the trust-point for the app, and manages selection of the appropriate IDP. One RP-STS, many IP-STS's. Each of your Customer's IP-STS gets set up as a Claims Provider Trust in AD FS.
As always, Vittorio has already covered the subject better than I could.
Authenticate to Webapi, using oauth provider (FB etc) client side only (HTML5 /JS phone app).
This is a tricky one,
So I can authenticate to our webapi using a username and password, using js from a HTML client, passing username & password as parameters over HTTPS we can set the user to authorised so they can access additional controller(s) for DB updates etc, so far so good bear with me.
I can authenticate to FB, using MVC and set the user to authorised.
I can do the same with HTML & JS client side (hooray), now how would I then authorise the controller, OK I get the users email from FB, so what, anyone could pass that. Suppose I could redirect to a MVC page (from the client) and then set auth on the controller(s) that way, but that's just not good (sending the user out the app, or a pop window).
What's the best method to authenticate the user from the client and authorise webapi controllers at the same time securely, do I have to re-direct the user to a mvc page and do it that way, how are other's handling this for phone apps / phone gap / intel xdk ?
The method apparently is, example facebook, but process is the same for any oauth provider ,
obtain access token by getting user to sign in/on.
Verify Token is genuine using server API (in FB's case graph API)
Client is happily logged in, until access token expires.
On expire(2 hours is the default), redirect user to login again, app is known it should authenticate without signing in again, unless user has revoked authorisation on your app.
here's a link on how to handle expire access token (examples are PHP)
Not exactly elegant, but it is what it is, and I thought It was only for super geeks!
Sorry to answer my own question