We have SOAP web services in production that are relying on SOAP Headers (containing plain client credentials) for the authentication. The WS are used in heterogeneous environments with .NET/Java/PHP/Python/C++ clients both web app or desktop app.
We are considering a v2 for those WS and I am wondering what are considered as the best practices for WS SOAP authentication? (reasonably secure, yet easy to handle on a wide variety of platforms).
The easiest way to handle it across a variety of platforms is to use HTTP basic authentication and HTTPS for the transport layer. WS-Security would be good if your needs go beyond simple username/password but the support is going to vary quite a bit between platforms. HTTP authentication is supported by every decent SOAP implementation.
If you have to roll it all yourself and can't use HTTPS, I'd suggest the hash-based UsernameToken portion of WS-Security. It's pretty secure and fairly easy to implement as long as your libraries have the hashing functions.
If you're doing web services, I wouldn't rely on HTTP for authentication.
WS-Security as a whole is way too big.
The way I have tackled this in the past is to use the standard WS-* features.
Instead of using the authentication feature we set the message header integrity feature on. This requires both sides of the dialog have access to public/private key pair and detects any tampering of the username field in the header. So you can be sure whoever sent the message and set the user id has access to the private key.
This provides a reasonable level of integrity if the keys are managed properly.
Related
We have a vendor supplied solution that requires a username and password to utilize their APIs exposed as a web service. They are to be included in the actual xml of the call. We obviously don't like that.
Does anyone know of any product, system, whatever, that we can have calling systems authenticate to with token based security, which would then inject the username password and forward the request in a secure zone accessible by the product but not the outside callers. And of course return the response through.
For example:
The Authentication/Proxy service has a name - Security Token Service (STS). oAuth token exchange working draft has a good summary of STS and its purpose:
A Security Token Service (STS) is a service capable of validating
security tokens provided to it and issuing new security tokens in
response, which enables clients to obtain appropriate access
credentials for resources in heterogeneous environments or across
security domains.
Web Service clients have used WS-Trust [WS-Trust]
as the protocol to interact with an STS for token exchange. While
WS-Trust uses XML and SOAP, the trend in modern Web development has
been towards RESTful patterns and JSON. The OAuth 2.0 Authorization
Framework [RFC6749] and OAuth 2.0 Bearer Tokens [RFC6750] have emerged
as popular standards for authorizing third-party applications' access
to HTTP and RESTful resources.
The conventional OAuth 2.0 interaction
involves the exchange of some representation of resource owner
authorization for an access token, which has proven to be an extremely
useful pattern in practice. However, its input and output are
somewhat too constrained as is to fully accommodate a security token
exchange framework.
Most STSes (incl. the type specified by oAuth token exchange draft) do not deal with heterogeneous tokens as your use case requires beyond, say, oAuth to SAML or vice versa. The solution to your use case is most likely going to involve a custom-coded STS. We've implemented STSes that translate oAuth/SAML to anything (e.g. SOAP with a custom credentials header like yours) for our clients using a variety of products/stacks/platforms/etc.
We often use Salesforce as the platform, it provides a lot of plumbing that helps with this use case. To be fair, similar plumbing is available in quite a few platforms and stacks - from the big 3 (AWS/GCP/Azure) to Java/Python/Ruby/Node/Go with appropriate libraries to identity & access management products such as Keycloak.
I would go for the #identigral STS proposal. As #identigral mentioned, the recommendation is to use some Identity Management (IdM) such as Keycloak to provide the OAuth 2.0 tokens and in the near future convince your vendor to use some IdM. To see an example on how to generate Keycloak tokens check this repo and also this Stackoverflow question. For your use case I see three possible solutions:
If you are developing things with Java I would go for an API Gateway such as Netflix Zuul. Spring framework supports Zuul and apply OAuth 2.0 tokens to Zuul is a very good option. For the config part again Spring provides Cloud Config to store global configuration for your component and it can be easily connected with Zuul.
Use some commercial tool such as Google Apigee. Take a look at it, everything described in point 1.) can be configured using Apigee at an API level covering multiple programming languages.
You can also use a reverse proxy as Proxy API Gateway with Security such as Nginx or Traefik.
Any solution can be good for you, it depends on your specific use case.
We are altering our webservices to require an application using them to provide information on the real user who is requesting the data. For REST services we are implementing this using an X-On-Behalf-Of HTTP header. Should we do the same for SOAP services? Or better put it in a custom SOAP request header? What are best practices in this area?
Though answer depends on internals of your application architecture and other design principals you might have followed.
Its ideal to keep Rest/SOAP services implemented the almost same security Model, hence if you're planing to use `X-On-Behalf-Of' HTTP, it make sense to use same in case of SOAP services as well.
But, in case of SOAP it you're using WS-Security or some Kind of Custom SOAP Header to do Authentication/Authorization in every SOAP Call, it makes more sense to Modify SOAP header itself to get the additional On-Behalf-Of' detail as well rather then Custom HTTP Header forX-on-behalf-of`
Refer Message 2 - WS-Trust Token Exchange Request section for more details.
I am starting a new project (a web application) and would like it to retrieve and submit the most of its data through REST web services with AJAX. But I hardly have a good idea of how to ensure a web service to know who is accessing it and only give the data to those who are eligible.
REST web services are stateless, so the authentication should also be stateless.
The most commonly used method for this authentication is to use HTTP authentication headers (details here --> http://www.ietf.org/rfc/rfc2617.txt). Here the pre-requisite is that your should be using SSL\HTTPS otherwise these HTTP authentication headers will become vulnerable to Man in Middle Attack.
If your website doesn't use and SSL then you should probably look to other methods of authentication, this (http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/) article discusses in detail about all those methods. It basically describes mechanisms which are used by Amazon Web Services to authenticate non SSL reqeuets.
Hope this will help.
I am developing a REST web service with Scala and LIFT and nave hardly any good idea on how to authenticate a client. I was thinking about a standard HTTP authentication, but found out it is very insecure as it passes passwords over a network in b64-encoded plain text. So how do I better do it?
If you want authentication to be secure against being observed in transit, your only realistic option is HTTPS. Technically, there are key-exchange protocols like Diffie-Hellman, but they aren't widely supported.
But the problem of observing packets in flight is almost a nonexistent one. In a shared LAN, it is possible, though not necessarily easy, to use a tap like FireSheep -- but it typically would be easier and more effective to walk over to the guy's computer and install a key-logger.
Basic authentication will pass password and user name in (nearly) clear text. If you use digest authentication instead it will still be prone to man-in-the-middle eavesdropping, but you should be safer from password theft and session takeover. This chapter in Exploring Lift have some information about digest authentication in lift: http://exploring.liftweb.net/master/index-9.html
We currently have a SOAP based web service that our in house applications use to authenticate users. Basically, they send a SOAP request with the username and password. The web service authenticates their credentials against our data store and returns user information if the authentication is successful. The web service is secured using BASIC authentication and SSL.
We need to make modifications to this web service and I was considering re-writing it as a REST service. The REST services I have created in the past have been fairly simple and had no need for security. I have never created a REST service that used sensitive information, so I have a couple of questions / concerns:
First, is there a best practice for sending sensitive query parameters (user credentials) to a REST service securely? I can still use the BASIC authentication and SSL.
Second, if I send a query to a REST service using POST, is it still considered RESTful, or is GET required for REST queries?
You can use SSL and Basic authentication with REST web services as well.
HTTP GET is usually used for data retrieval (queries) but you can use HTTP POST as well. GET is especially useful if you can use any type of HTTP caching. POST is usefull if you need to transfer a lot of data to define your query or if your web service operation expects some complex data format instead of simple arguments.
Instead of doing the authentication via REST, you might also consider a networked authentication protocol to use in conjunction with web services. Technologies like Kerberos and OAuth were designed for these sorts of use cases.
To answer your questions, however:
REST encourages you to leverage HTTP and related protocols, so using SSL and BASIC authentication is quite appropriate.
REST encourages the use of not just GET and POST, but even other HTTP "verbs" such as PUT and DELETE. Use GET only for idempotent operations with no side-effects.
Going from SOAP to REST is taking a step backward as far as security goes.
As far as best practices:
Don't roll your own security. Use a framework or existing library that has been peer-reviewed and tested.
Don't pass unencrypted static keys. If you're using HTTP Basic and sending it across the wire, encrypt it.
Ideally, use hash-based message authentication code (HMAC) because it's the most secure.
Why REST security doesn't exist