I want to create a simple web service authorize module. Don’t want to use 3rd party authorizing component. I’m thinking to set it up like this. Let’s say Client want to call the Foo() API on the server.
Client – Connect with Server Credentials (basic authentication to IIS over SSL) → Server
If successful (else exit)
Client – Call Login(credentials) API (login to the system) → Server
If Successful (else empty string or something like that)
Server – Session ID or token (expire with in a period) → Client
Client – Call Foo(sessionID/token) (call APIs with Session ID) → Server
I know there should a component that does this authentication, but I rather use .NET Framework built in components, (don’t want to use 3rd party components.) If you know any let me know. Is this a valid pattern, I'm user someone has done this before. Do you think I should use Session ID to send back, or send back some kind of Guid or token?
Related
Is it possible to block connections to a web service (server) from outside its domain?
For example consider a web app that fetches data from Twitter's API using Twitter's "application only auth". The web app's client uses AJAX to call it's own server, which in turn calls Twitter's API with Twitter's token.
While the token is never exposed to the client side code is there anything to stop an outside server side app from calling the web app's server using the URLs used by the client and for example exhausting the Twitter tokens rate limits?
Is it possible to block connections to a web service (server) from outside its domain?
Certainly. Set your web server's access control lists to drop connections from outside of your IP range. Alternately, install a firewall. That's very straightforward, but I suspect you mean something else by "outside its domain?"
From your description, you seem to be really asking whether you verify that you're only talking to your own client application. As a general rule, no. You can authenticate users. That's easy. If the user isn't logged in and authorized to use your service, you don't forward requests to Twitter. But you can't authenticate applications.
If you're going to accept any user who shows up, you can't stop them from using whatever client they want. There is no way to ensure that it is your unmodified client if you've allowed it to be run on their machine. They can always modify it, and they can always send you arbitrary traffic from other programs and you can't tell the difference. On the network, bytes are bytes.
It's not all hopeless; there are things you can do. See https://stackoverflow.com/a/9183066/97337 for another version of this question, and links to several other versions of the question. (They're not exactly duplicates in how they're asked, but they all wind up being basically the same answer.)
You should secure your web service with user and password security or certificate security. The basic idea is that the web service client must authenticate in order to call your web service.
Here are some technics (there are others or variations):
1) HTTP basic authentication and HTTPS
2) Mutual SSL authentication - Also called two-way authentication, is a process in which both entities authenticate with each other. The server presents a certificate to the client and the client present a certificate to the server.
3) With SOAP web services you can use WS-Security standard.
4) OAuth framework
5) With Rest services you can use options 1), 2), 4). Or implement one by your own. This are good recomendations.
As you can see, there are a lot of ways to secure a web service.
I am just woundering, how we can use RESTful architecture/webservice to implement online shopping kind of application ?
Say we want to build anything like Amazon where user can login and do shopping. First time, we will perform authentication using HTTP Basic or any other security mechanism, which is fine.
Now, when user made a second request he need to send some authorization code or sessionId or something else so that server will know this is the same user which has logon earlier. But, RESTful webservice is stateless so we are not suppose to store old session related stuff. In that case how we can authenticate user ?
I read something about cliet and server certificates but it is applicable to application where two different services are communicating with each other. Am I correct ?
I am new to webservice :-) so this type of silly question came to my mind.
The http basic auth stores the username and password on the client side, and it sends it again with every request. So by REST you have to send these identification factors and authenticate by every request...
You can cache the authentication mechanism if you want it to be faster...
This is an important thing by REST... REST stores the session on client side, not on server side... If you want store something important on server side, then it has to be a resource or a property of a resource...
If you allow somebody to write 3rd party application (another client for your REST service), then the user should accept that this 3rd party application can send requests in his/her name. Ofc. the user does not want to share his/her password, so give permissions to 3rd party applications is a hard stuff. For example oauth solves this problem...
The basic concept by 3rd party applications (clients), that you ask the user whether it allows them to send certain requests or not. For example by facebook it asks, if you want share your identity, list of acquaintances, etc... and you allow to send posts in your behalf, etc... After you clicked ok, the REST application should store that information and give the client permissions to your account. How to check who sends the requests? Ofc. CSRF is not allowed, so the 3rd party client cannot send a cross domain request on your behalf with the client you are using. So it has to send its requests trough a different connection, probably with curl. What should it send? Ofc. the request details. What else? Its identity (an api key) and your identity. This is the most basic approach.
There are other solutions. You can use a similar approach to what you are using by storing passwords in a database. You store only hashes of the passwords hashed with a slow algorithm. By the authentication you create the hash again on the given password. When the stored hash is equal with the newly created, then the application accepts the identity and grants access to the account. You can use the same approach by requests. The 3rd party client requires a hash for a request. After that it sends the request with the hash it got, and by getting the request, the server compares that hash with the hash it creates based on the content of the request. If they are equal, the request is valid. This is cool stuff, because it prevents a CSRF attack on a 3rd party client as well...
I guess there are many other, more complex approaches, I don't know, I am not a security expert and probably you won't be either. You just have to understand the basics and use a tool for example oauth if you want to allow 3rd party access to your api. If you don't want that, then probably you don't need a REST application, just a simple web application... That depends on your needs, visitor count, etc...
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.
I'm working on an iPhone app that uses xAuth to login to Twitter. The app also communicates with my own web service. Rather than maintain a user model inside the web service, I'd like to just allow anyone who's already authenticated via Twitter to make requests.
The high-level use case is this: the user logs into and interacts with Twitter through the app. They can also interact with my web service through the app. The web service itself never interacts with Twitter. Instead of maintaining a separate authentication system on my side, I'd like the server to say "OK, if Twitter says you're #joshfrench then you can have access."
I'm not sure how I should validate requests on the server side, though. How would I pass some proof of authentication from the mobile client to my web service? Can I send along the existing Twitter token and verify it from the server? Or somehow sign the request with my Twitter app's credentials? Is this even a valid use of OAuth?
If you store your twitter app key and secret on both he iphone app and your server, and then somehow transmit the user's oauth token (also called "access token") key/secret from the iphone app to the server, then you can do the same type of api calls from the server.
consumer = OAuth::Consumer.new(app_key, app_secret, …)
access_token = OAuth::AccessToken.new(consumer, user_key, user_secret)
response = access_token.get('/stuff.xml')
So, is it Okay to transmit that info from the app to the server? If you do it securely, and it's within the user's expectation for how the app behaves, then it's a perfectly fine use of oauth.
It's possible that it's not allowed by Twitter's terms of service -- I could imagine there being something that says you can't transfer a user's access secret across the network, or some such thing. (total wild speculation, I don't think it's particularly likely that that's the case)
I have been doing some research lately about best approaches to authenticating web services calls (REST SOAP or whatever). But none of the Approaches convinced me... But i still can't a make a choise...
Some talk about SSL and http basic authentication -login/password- which just seems weird for a machine (i mean having to assign a login/password to a machine, or is it not ?).
Some others say API keys (seems like these scheme is more used for tracking and not realy for securing).
Some say tokens (like session IDs) but shouldn't we stay stateless (especially if in REST style) ?
In my use case, when a remote app is calling one of our web services, i have to authenticate the calling application obviously, and the call must - if applicable - tell me which user it impersonates so i can deal with authorization later.
Any thoughts ?
So, you have User -> clientServer -> yourServer, yes?
You need to authenticate clientServer -> yourServer, to make sure not just anyone can talk to your server.
If this is an established trust relationship (i.e. you guys chat, sign documents, and do other things "out of band"), then you can simply use SSL certs, certs that you can sign.
Basically you set up your own Certificate Authority, create a root certificate, and then create a client certificate signed by that root certificate.
You then send that certificate to the clientServer, and don't let anyone connect to your service that doesn't have a certificate signed by your root certificate.
If the client ever ceases their relationship, you can revoke their cert and they can't talk to you any more.
As for identifying the User, that will need to be part of the API. The Client should authenticate them properly, and then forward any credentials to you that you require.
That can be a first class part of your web service (like a parameter), or if you use SOAP it can be passed along in a SAML attachment in the SOAP header, that you can then extract.
WS-Security has about 8000 ways of securing SOAP web services, as you may have discovered.
So, it kind of depends on what you want to do, and other requirements. But given what little you have, this should work peachy.