Microsoft sync framework Authentication - web-services

I'm very novice when it comes to web applications and ASP.
Recently, I've been experimenting with the Microsoft Sync Toolkit to synchronize databases over a OData web service.
The obvious question here is: Once the service is set up and published - so it is open for anyone knowing the URL - how to prevent unauthorized users from accessing this service.
Please note: Basic authentication of forms authentication - as far my little web development knowledge reaches - doesn't seem to be appropriate for this task, as it's not a web page that the client is trying to reach - where the page can display / or re-direct a logon request - it's a service that we are accessing here.
To make things more difficult, for the client-side syncing I'm using a 3rd party library/sync-provider that only accepts a URL for the service. So, there's no way (I think) I can experiment with incorporating login credentials inside a request header etc.
I assume the best bet would be embedding the login credentials inside the URL and use that for the 3rd party library.
Can somebody please direct me how to to set up such thing on the server? I would prefer to have somehow somewhere in the server-side code a place where I can check for the credentials and based upon it to proceed or abort (return 401) the service request.
I could not find any place where to hook such code into the sync service. Although somebody in MSDN suggested to handle the _OnBeginSyncRequest event, there is no way to access the web-request header from within that method.
Is there by-any-chance a global object accessible from everywhere from which I can access the request header? Could anyone please help with this?
And last, I would prefer a plain User / Password string pair. It should not necessarily (or rather not) have anything to do with windows or directory accounts. I would prefer in my code to simple check against plain strings, such if(userStr == "Authenticated user" && passwordStr == "Correct Password").

if you are using SOAP web service, you can use WS-Security usernametoken which adds your user name and password to the request header, otherwise you can add username and password as parameters in your webservice and then simply validate it on the server side. i.e.
instead of
bool SyncData(datatable)
it becomes
bool SyncData(datatable, username, password)
note for web service you will authenticate per call, if you want to do it per session, you need first login with username password, retrieves a token than on each subsequent call your service with the token.
You would also use SSL to secure the channel so username and password aren't transmitted as plain text.

Related

Advice how to implement a simple user login and authenication

We are in the process of building a simple Android application together with a simple back-end web server to allow the user to get some information form the server.
We need to login the user, to make sure he is authorized to view the data, but apart form that I do not think we have particular security concerns.
I need some advice on how we can implement the server to keep things as simple as possible.
For example, we could use something like this to make sure the user is authorized to see the data:
http://ourwebservice/user/password/viewsuchandsuchdata
Is that a good way of doing things?
Do you have any suggestions or comments?
There are many ways to secure web-services.
The simplest is possible "Basic Auth" (http://en.wikipedia.org/wiki/Basic_access_authentication). On every request, you send the user credentials in the "Authorization" HTTP header concatenated with ":" and base 64 encoded. To keep it safe, you need to make sure the connection to your web-server is using SSL (HTTPS), otherwise the user password could be intercepted.
Another "newer" solution is OAuth2, and in your case the "Resource Owner Credentials" flow. Instead of passing the user credentials on every request, you use them once to "exchange" them for a short-lived access token issued by your server. Then on any request to the web-service you pass that access token in lieu of authentication. The server must then verify that the token is valid and find out for which user it was issued. For more info see this article: http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified.
There are potentially many more "custom" ways of doing authentication...
Going the OAuth2 flow is probably more difficult but there are lots of open-source libraries out there to help you build a OAuth2 provider (http://oauth.net/2/). The advantage is that you don't have to store the user password on the device, which is safer (the less you touch passwords, the better).

How can I implement user authentication for ColdFusion Web Services called from a mobile application?

I am developing several Web Services that will be accessed by a mobile application. I have several requirements:
Each user will need to sign in with their own User ID and Password (the same User ID and Password they use to sign into the website).
Every Web Service request will need to be authenticated to ensure that the request is coming from the mobile app(s).
Every Web Service request will need to authenticate the user, since there is user-specific fucntionality built in, and access will need to be blocked if the user's account is disabled.
Let's assume that OAuth is not an option.
In order to ensure that Web Service requests are coming only from the mobile app(s), I am planning to use HTTP Basic Authentication in IIS (the mobile app(s) will need to have a User Account setup in Windows Server and the mobile app will need to store the User Name & Password and pass these in the header).
Next is the User Authentication for each Web Service request. Would it be suitable to encrypt the User ID, Password, and some shared secret key (a "pepper", of sort) with AES-256, pass that encrypted string as a parameter with each request (over HTTPS, of course), and then decrypt and parse it on the server to authenticate? This is the existing plan, but something just doesnt seem right about it - like it's not "secure enough".
What else can I do to properly authenticate users for Web Service requests?
I recently went through this problem and asked opinions from a group of senior people about how they solve the problem. Opinions were varied, but one consistent feeling is that your level of security depends on the use case of your application. Are you doing online banking or storing medical records? Then your security needs may be quite high. Social networking? Maybe not so much.
Basic Authentication is generally fine when encrypted over SSL, ColdFusion works well with it. If you use Basic Auth, make sure to encrypt your traffic with 1024-bit keys or better. Don't authenticate every request with username/password - that's unnecessary. Authenticate the first request, set a session token, and rely on the session token for your identification of users.
Set a polling mechanism from the client to the server to keep the session alive - set the session timeout to 30 minutes and the polling frequency at 25 minutes, for example. Otherwise you may need to re-authenticate expired sessions. Again, how you approach this part of the solution depends on your paranoia level, which depends on what kind of data/app you are dealing with.
Cookies, and therefore sessions, should work fine in iOS apps. If you use sessions to verify identity after authentication, make sure your session cookies are memory-only (set at the server level).
Check the SSL implementation of your server against the Qualysis SSL Test:
https://www.ssllabs.com/ssltest/
The report will give you a surprising amount of detail about the strength of your SSL implementation.
Lastly, consider implementing two-factor authentication to combat password theft.
If you ignore the SSL advice and plan on encrypting your password and communicating over an insecure channel, look at the Kerberos protocol for a well-known example of how to authenticate securely:
http://en.wikipedia.org/wiki/Kerberos_%28protocol%29
Yes, you can use Basic Authentication but that means the client will need to store the username/password in plain text, and also send them over in plain text. Sending part is sort of fine if it's under HTTPS, but storing username/password in plain text may not be a good idea, unless you're using some secure key store.
Let's assume you have decided that Basic Authentication is the way to go, and you want to make use of the official CF way of supporting that, then you can use CFLOGIN.name & CFLOGIN.password. You may also check out Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion. In the remote cfc side, always validate the username/password, or return some sort of token and asks the client to use that token going forward. The token can be cfid+cftoken if you like, or even roll your own that never expires. If you use cfid+cftoken, and send them over as cookie or in body along with your web service call, I believe you can resume the session if you so choose.

Secure way to contact REST API for use with Html 5 / Javascript

This is a similar situation to the one raised in this question:
Javascript Calling a Rest API with App Name and App Password - How Can i Secure it
Here is the architecture overview:
The site is Html5/jquerymobile
It contacts what I call a "Wrapper" service.... This is a REST API I wrote in C#, to contact another 3rd party REST API. I do this because there are credentials in the Header and the API uses Basic Authentication. Credentials are therefore not publicized as they are only known server-side.
My "Wrapper" service does not currently implement any additional security. It is currently accessible from anywhere. The easiest and quickest way to lock it down is to restrict by IP, so no other IP anywhere except the server can actually contact my wrapper service.
The questions:
Is the locking by IP the only way to ensure that the API won't get hammered if it was otherwise accessible from anywhere?
If I convert this using Phonegap (which I have... and deployed successfully on Android), obviously the native app won't work if the web service is restricted.
Is there a way around this so I can allow traffic only from the mobile app, and not from any other source? I'm thinking along the lines of MD5 hash or something that could be sent to the wrapper API.. but unfortunately I'm thinking that info can easily be "sniffed".
Is my only viable option here to release the app as a web app, forcing browser use, thereby removing any concerns about allowing my web service to be hammered??
I believe the answer to this is a combination of a user token and encrypting the message through SSL.
The server can issue a valid user a token so we can identify him in future requests.
Encrypting it via SSL will ensure that this token cannot be sniffed.
https://security.stackexchange.com/questions/12531/ssl-with-get-and-post

How do I implement login in a RESTful web service?

I am building a web application with a services layer. The services layer is going to be built using a RESTful design. The thinking is that some time in the future we may build other applications (iPhone, Android, etc.) that use the same services layer as the web application. My question is this - how do I implement login? I think I am having trouble moving from a more traditional verb based design to a resource based design. If I was building this with SOAP I would probably have a method called Login. In REST I should have a resource. I am having difficulty understanding how I should construct my URI for a login. Should it be something like this:
http://myservice/{username}?p={password}
EDIT: The front end web application uses the traditional ASP.NET framework for authentication. However at some point in the authentication process I need to validate the supplied credentials. In a traditional web application I would do a database lookup. But in this scenario I am calling a service instead of doing a database lookup. So I need something in the service that will validate the supplied credentials. And in addition to validating the supplied credentials I probably also need some sort of information about the user after they have successfully authenticated - things like their full name, their ID, etc. I hope this makes the question clearer.
Or am I not thinking about this the right way? I feel like I am having difficulty describing my question correctly.
Corey
As S.Lott pointed out already, we have a two folded things here: Login and authentication
Authentication is out-of-scope here, as this is widely discussed and there is common agreement. However, what do we actually need for a client successfully authenticate itself against a RESTful web service? Right, some kind of token, let's call it access-token.
Client) So, all I need is an access-token, but how to get such RESTfully?
Server) Why not simply creating it?
Client) How comes?
Server) For me an access-token is nothing else than a resource. Thus, I'll create one for you in exchange for your username and password.
Thus, the server could offer the resource URL "/accesstokens", for POSTing the username and password to, returning the link to the newly created resource "/accesstokens/{accesstoken}".
Alternatively, you return a document containing the access-token and a href with the resource's link:
<access-token
id="{access token id goes here; e.g. GUID}"
href="/accesstokens/{id}"
/>
Most probably, you don't actually create the access-token as a subresource and thus, won't include its href in the response.
However, if you do so, the client could generate the link on its behalf or not? No!
Remember, truly RESTful web services link resources together in a way that the client can navigate itself without the need for generating any resource links.
The final question you probably have is if you should POST the username and password as a HTML form or as a document, e.g. XML or JSON - it depends... :-)
You don't "login". You "authenticate". World of difference.
You have lots of authentication alternatives.
HTTP Basic, Digest, NTLM and AWS S3 Authentication
HTTP Basic and Digest authentication. This uses the HTTP_AUTHORIZATION header. This is very nice, very simple. But can lead to a lot of traffic.
Username/Signature authentication. Sometimes called "ID and KEY" authentication. This can use a query string.
?username=this&signature=some-big-hex-digest
This is what places like Amazon use. The username is the "id". The "key" is a digest, similar to the one used for HTTP Digest authentication. Both sides have to agree on the digest to proceed.
Some kind of cookie-based authentication. OpenAM, for example, can be configured as an agent to authenticate and provide a cookie that your RESTful web server can then use. The client would authenticate first, and then provide the cookie with each RESTful request.
Great question, well posed. I really like Patrick's answer. I use something like
-/users/{username}/loginsession
With POST and GET being handled. So I post a new login session with credentials and I can then view the current session as a resource via the GET.
The resource is a login session, and that may have an access token or auth code, expiry, etc.
Oddly enough, my MVC caller must itself present a key/bearer token via a header to prove that it has the right to try and create new login sessions since the MVC site is a client of the API.
Edit
I think some other answers and comments here are solving the issue with an out-of-band shared secret and just authenticating with a header. That's fine in many situations or for service-to-service calls.
The other solution is to flow a token, OAuth or JWT or otherwise, which means the "login" has already taken place by another process, probably a normal login UI in a browser which is based around a form POST.
My answer is for the service that sits behind that UI, assuming you want login and auth and user management placed in a REST service and not in the site MVC code. It IS the user login service.
It also allows other services to "login" and get an expiring token, instead of using a pre-shared key, as well as test scripts in a CLI or Postman.
Since quite a bit has changed since 2011...
If you're open to using a 3rd party tool, and slightly deviating from REST slightly for the web UI, consider http://shiro.apache.org.
Shiro basically gives you a servlet filter purposed for authentication as well as authorization. You can utilize all of the login methods listed by #S.Lott, including a simple form based authentication.
Filter the rest URLs that require authentication, and Shiro will do the rest.
I'm currently using this in my own project and it has worked pretty well for me thus far.
Here's something else people may be interested in.
https://github.com/PE-INTERNATIONAL/shiro-jersey#readme
The first thing to understand about REST is that its a Token based resource access.Unlike traditional ways, access is granted based on token validation. In simple words if you have right token, you can access resources.Now there is lot of whole other stuff for token creation and manipulation.
For your first question, you can design a Restfull API. Credentials(Username and password) will be passed to your service layer.Service layer then validates these credentials and grant a token.Credentials can be either simple username/password or can be SSL certificates. SSL certificates uses the OAUTH protocol and are more secure.
You can design your URI like this-
URI for token request-> http://myservice/some-directory/token?
(You can pass Credentilals in this URI for Token)
To use this token for resource access you can add this [Authorization:Bearer (token)] to your http header.
This token can be utilized by the customer to access different component of your service layer. You can also change the expiry period of this token to prevent misuse.
For your second question one thing you can do is that you grant different token to access different resource components of your service layer. For this you can specify resource parameter in your token, and grand permission based on this field.
You can also follow these links for more information-
http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
I have faced the same problem before. Login does not translate nicely to resource based design.
The way I usually handle it is by having Login resource and passing username and password on the parameter string, basically doing
GET on http://myservice/login?u={username}&p={password}
The response is some kind of session or auth string that can then be passed to other APIs for validation.
An alternative to doing GET on the login resource is doing a POST, REST purists will probably not like me now :), and passing in the creds in the body. The response would be the same.

RESTful user authentication service

Hey folks, this seems to have been discussion fairly often but I want to make a simple, watered down question around doing authentication with RESTful services. The scenario is as follows:
There is a system that houses registered users for an application. The system exposes a RESTful API for accessing these users.
There is a front-end application that has a login form. The application can either be internal, or external.
The front-end application needs to use the data in the User system to authenticate a user.
The question now is how to authenticate a user whose credentials (username/password) are entered in the client application against the data in the User system such that it is secure and performant? For the sake of this question, suppose the client application is internal to some sort of Intranet but the applications will not reside on the same machine and may only communicate through the service.
I understand the idea of having the application being "hypermedia driven" but we should be able to provide filtering/searching services. For example, consider the resources and API as below:
http://example.com/users
GET - retrieves all users (paged, hypermedia driven)
POST - creates new user
PUT/DELETE not supported
http://example.com/users/[id]
GET - returns a full representation of a user with id = {id}
PUT - updates user, takes in any predefined media type
DELETE - deletes the user (with appropriate authorization)
POST not supported
Based on the above, my idea would be have the client application GET on the user listing, filtering by username. The service will return the hashed password and salt to the client, the client will perform the authentication.
Thoughts?
If I understand your question correctly, you are looking to implement a generic service that will handle authentication, so that you can re-use it for different applications.
I suggest you take a look at OAuth which has been built for precisely this problem domain.
Passing the username and the salt back is unnecessary and a real security risk.
Perhaps you could consider this approach:
Have the client pass the username and password to the server via Basic Authentication
The server fetches the encrypted password for the username along wiht the salt
The server encrypts the given password using some encryption method, using the salt to assist the algorithm (Ruby code follows):
def User.authenticate(login, password)
ok = false
user = User.find_by_login(login)
if user
#
# user contains the salt, it isn't passed from the client
#
expected_password = hash_password(password, user.salt)
ok = (user.password == expected_password)
end
return ok
end
There are multiple places to use this kind of approach but I like to do it in Rack.
Last point, do it all on a HTTPS connection
Stormpath
Stormpath company dedicated to providing a user login management API and service for developers. They use a REST JSON approach.
There are some other companies that seem to dabble in this new area of authentication-as-a-service, but Stormpath is the only one I know of that is dedicated to it.
First, you don't want the client to perform the authentication, as it then would be trivial to write a client that breaks into your service.
Instead, just use an authentication mechanism like HTTP Basic or HTTP Digest.
Note that if you're using Java, the Restlet framework provides interceptors, called Guards, which support these and other mechanisms. I highly recommend Restlet.
Mozilla Persona
Since this question was posted, the Mozilla Foundation (the maker of the Firefox browser) has taken on the problem of simple user authentication. Their solution is Mozilla Persona, "a sign-in system for the Web". Designed to be easy for users and for developers. The user's identity is an email address. See Wikipedia article.
Update
Mozilla has basically given up work on Persona but not quite killed the project.