I have a set of .NET applications running in a public web environment which connect to a centralized component made up of web pages and web services.
Is there any way to implement a security feature to make the centralized web pages be sure of the caller applications identity? Making a post and supplying a querystring parameter stating the caller application is a naive solution, someone can manually change it.
Any ideas? Tks in advance.
Assign secret keys to each client-server pair and use them to sign messages passed between client and server (using HMAC for example).
TLS/SSL/HTTP. You just need to enable client authentication. SSL is usually only used in the scenario where the server needs to be authenticated. But the server end can be configured to authenticate the client also. Digital certs need to be installed on both ends. This then uses all the appropriate crypto to do the job, ie. public authentication, establishment of secure channel, using Diffie-Hellman, RSA, AES/3DES, whatever you configure.
Take a look at this post. Good place to start.
Another option, perhaps have you look at OpenID?
The current situation:
Servers A, B, and C are trusted and controlled by you. A visitor comes to site A and views a page that sends data to site C, and the data contains something like "origin=A". We're concerned that the user will change that to "origin=B".
A simple fix:
You control all three servers, so let them communicate to verify incoming data. For example, A will change "origin=A" to "origin=A&token=12345", where the token value is random. The user tries to tamper with it and sends "origin=B&token=12345" to server C. C makes a trusted connection to B, saying "Did you send someone to me with token 12345?" B says "Nope" and C knows to reject the request.
This can be arbitrarily elaborate, depending on your needs and whether you're using https. Maybe tokens expire after a certain time period. Maybe they're tied to IP address. The point is that server C verifies any information that comes from the end user with servers A and B.
Are you asking about single-sign-on? (i.e. someone authenticated on AppA should also be able to use AppB and AppC without re-authenticating)
You can do this by configuring the machineKey for your apps so they can share asp.net authentication tokens.
The company I work for currently uses shared forms authentication cookies across the enterprise by using the same machine keys on each web server. However, this is not ideal if you wish to SSO across different domains and it's not very neat for windows app that need to come into the web farm to use the web service methods...
So, where we have to do this we are using SAML
But to clean this all up and make it more unified and more secure we are beginning to implement Geneva
If you communicate with the web services and web pages using http post, you avoid putting the info in a query string.
Send the data over https so that it cannot be tappered with.
You then need to make sure that the call is coming from your public web environment. One way of doing this is to use windows authentication, based on the identity of the application pool.
EDIT 1
Take a look at this link: http://www.codeproject.com/KB/WCF/WCFBasicHttpBinding.aspx
It shows how to set up windows authentication for WCF basic http binding.
Maybe look at the HTTP REFERER field. Under certain conditions this may be treated as reliable. In particular: An A mimic site won't send users from A to C according to HTTP REFERER.
Related
I have a JAX-RS application deployed under tomcat and a mobile app.
I would like to know how to make the webservice usable only by the mobile application, in other words, allow access only for a given application
When a request comes in across the internet, there's not really a safe way to be sure what application sent the request. Applications can identify themselves however they want. You could, if you want, attempt to hide credentials in your application, somehow, and have it log in with those credentials. But if anyone discovers those credentials, they can write a program that uses them to pretend to the your application. The problem is that you cannot count on any control over the client system. The client system can always be altered to pretend to be something it is not.
From my perspective, you can add username/encrypted password in the invoke request, and then compare it with the ones saved in the server side
If you really want to, you could implement some form of cryptography. For example, the JAX-RS service can send a 401 forbidden and provide a nonce for the client to sign with its private key, and then send back to the server in the Authorization header. Otherwise, stick to HTTP authentication. If you are communicating via HTTPS, you should be fine with basic auth.
I have created an API that should only be accessed by certain client applications.
The users of these applications do not (necessarily) have to log in to use the client application. I will hand out API keys, but these will be visible on the client app, so they can also be used by other applications (?).
Is there any way to make sure the requests are coming from a specific client application, for example because they are hosted on a certain domain? I guess origin headers can easily be spoofed.
API keys are typically used to authenticate applications to a server. You are not saying what type of client you are using (native, web app, JavaScript?) You're correct that the API key may be read by another application on the client if that client has the same permissions (running in the same security context) as your client.
You could use client certificates to have the application identify itself. But this may be a pretty heavy-handed solution depending on the security thread you're trying to mitigate. And even here an application in the same security context has access to the private key.
All other info in an HTTP request is easy to falsify.
I'm currently using Thinktecture's Identity Server as a security token service to handle the issuing of tokens based on username and password claims. This fits perfectly for a scenario where the authenticating client is an actual user authenticating against a web application for instance, but I'm now interested in scenario for when the authenticating party happens to be an independent process on the server that needs to establish a security token to pass to another server process. I'm ideally after a few pieces of advice here:
1. Is this a valid approach to authentication for server processes communicating with each other?
2. What if I were to move one of the server processes to a different machine talking across a TCP boundary instead perhaps? Is this approach still valid.
3. What ClaimTypes would I use for authentication of the process? And is the Thinktecture Identity Server happy to authenticate against these? I assume I'll probably have to write a custom authentication extension to it to do so...
Thanks very much,
Clint.
One of IdentityServer's authentication protocols is the "simple http" -- you pass in credentials and get back a token. This might be what you want.
Oh, there's also the WS-Trust endpoints as well.
We are using WCF services. Right now, we are using Windows Auth but this is not for long. Some services will sit outside the firewall and use username/password verified in the database.
My tech lead is "scared" at how easy any user can "Add Reference" to the services we have and just party on. He wants to "guard" the services by adding another identity - the application. He wants the service to accept requests from certain applications so the certain users cannot just use the service - add reference to it and call. It’s the notion of the application having an identity + credentials that is the operative principle here, as services on the network may need to authenticate those credentials prior to fulfilling a request, in order to prevent rogue code inside the network (i.e., NOT the application) from accessing services using “Joe User” end-user credentials.
Does this make any sense?
Then he believes the Juval Lowy's book has, in an Appendix that discusses sending more than one identity during a WCF call (Security Interceptor). There is no specific suggestion that all of those have to be end-user identities and if that is the case, one of those could be the identity of the application making the request.
How can this be done?
Thanks,
Sam
The problem with sending an application identity is that the secret used to confirm that identity has to be stored somewhere. If it is visible to one application on a machine then generally it will be visible to other applications running under the same identity.
Would your manager be happy with "it came from an authorised machine"? If that's the case you could simply use Client Certs
Its also worth taking a step back: if the user is authenticated and is authorized to perform the functionality they have requested, why do you care which application they came from - if they are who they say they are and they are allowed to do what they are requesting then why couldn't they use, say, fiddler to make the request - isn't that the point of a service (rather than a closely coupled client server app)?
You might want to look through Common Security Scenarios in the MSDN documentation to see if any of those options fit your needs.
The options that pops to my eye are Transport Security with Certificate Authentication and Message Security with Mutual Certificates. Both rely on X.509 certificates. The latter option is on the message level, so you can handle certificate delivery and security negotiation however you want.
To make it a lot harder for someone to add a reference to your service you could just remove the mex endpoint. This way it would be very difficult for a stranger to create a valid request message.
You can then distribute the WSDL manually, only to people you trust.
I have a specific Silverlight application, that is fed with data by a WCF-Service. I want to make sure, that the WCF-Service is only called by that specific Silverlight App. What is the best way to accomplish that and what do I have to do? It doesn't have to be a high security solution.
Thanks in advance,
Frank
Enable basic authentication (username/password) on the service. Create a single user which the Silverlight app will use to authenticate itself with the service.
Easier, but less secure, might be to just use some sort of identifier (only known to the Silverlight client) as a service parameter.
Both options are obviously most secure when implemented with HTTPS. This can be accomplished by using a server certificate.
You CANNOT restrict access to such a service. Your app will need access to whatever key/password you chose. It is trivial to decompile your app and extract the key. SSL/TLS will not help - because the password can be extracted from the compiled code.
This question has been asked quite a few times recently -
Ensure exclusive access to webservice
How to restrict access to my web service?
How can I create and use a web service in public but still restrict its use to only my app?
If your application is running anonymously then it's virtually impossible to be 100% secure.
How ever if your are requiring your users to authenticate then you should be able to make the service relatively secure by requiring their login credentials...
I don't know if it easy with WCF, but I guess you could do something using client certificates. I only used this approach for protecting websites and it was quite easy to do...