This sample demonstrates HTTP authentication support to secure services, as well as connect to already secured services
- Use Case
- The HTTP Authentication Schemes
- Securing Proxy Services with HTTP Basic and Digest Authentication
- Proxy Services performing authentication on behalf of users
- Related Topics and Extension
Use CaseThe HTTP protocol supports transport level request authentication, and the most common schemes are: Basic Authentication and the more secure Digest Authentication scheme and NTLM authentication. With large scale use of the Amazon S3 infrastructure, the AWS S3 authentication over REST is also being used in many systems connecting with the Amazon S3 infrastructure. This article explains these authentication schemes, and describes how Proxy services deployed on the UltraESB could use Basic or Digest authentication to secure backend services, and also shows how Basic, Digest, NTLM or AWS S3 secured services can be accessed through the UltraESB - by allowing the ESB to perform transparent authentication on behalf of the clients. Each of these schemes maybe used over HTTPS as well.
The HTTP Authentication Schemes
Pre-emptive and Challenge-response authentication
HTTP Authentication mechanisms can be briefly divided into two popular categories. Those that allow the authentication information to be passed along upfront with the request; and those that requires a dynamic response performed over a challenge presented by the server. Pre-emptive authentication can be considered as performing slightly better than challenge-response authentication that requires a re-issuing of the request with a response to the challenge presented. However a challenge-response authentication scheme would offer a higher level of security. The Basic and AWS S3 schemes typically supports pre-emptive authentication, while the Digest and NTLM schemes support challenge-response based authentication.
HTTP Basic Authentication is the most simple authentication scheme that's well described by the linked Wikipedia article. When pre-emptively used, it sends a HTTP header called 'Authorization' with the Base64 encoding of the "<username>:<password>" string as follows:
If the authentication information is validated successfully, the normal / expected response is returned. If authentication information was not passed when making a request to a secured resource (i.e. if the request above was issued without the 'Authorization' header) or if the credentials fail, the server would respond back with a HTTP status code of 401 as follows, requesting authentication - to which the request would then be re-issued by the client with the 'Authorization' header.
Note: The Basic authentication scheme sends the password in an easily decrypt-able manner, and thus is not safe unless the request is made over an SSL secured connection.
HTTP Digest Authentication is again well described by the linked article from Wikipedia. A request that does not provide valid authentication credentials fails with a response from the server with a challenge as follows.
A client is expected to re-submit the request as a response to the challenge presented by the server (nonce, opaque, etc - See Wikipedia article for more details)
NTLM authentication is described by its Wikipedia definition and some of its references, especially the one by Eric Glass. This could be a complex protocol to understand to someone unfamiliar with it, and involves multiple steps which are best explained from the previous links.
Amazon S3 Authentication
The Amazon S3 authentication scheme is defined by this article, and uses the AWSAccessKeyId and the AWSSecretAccessKey of the client to authenticate. A typical request could be presented as follows where the authentication header is computed as "Authorization: AWS AWSAccessKeyId:Signature" with the <Signature> component calculated with respect to the HTTP verb, request URI, date and other headers signed with the AWSSecretAccessKey.
Securing Proxy Services with HTTP Basic and Digest Authentication
The UltraESB sample # 110 includes a complete - fully functional and annotated configuration used by each example presented in this article. It could be started and used to try out all of the following scenarios and more. The graphical SOA ToolBox will help to test some of the scenarios or a Web Browser may be used as the client. To start this example, invoke Sample # 110 configuration as follows from the /bin directory of your installation
The scenarios first define a service "rest-mock" that's exposed over HTTP port 8281 and secured with Basic authentication, as well as over HTTP port 8282 and secured with Digest authentication. This service is hosted as a service implementation on the UltraESB, and will return request information. Its available at the following URLs:
Accessing the above URLs after starting the sample #110 configuration will request for user credentials using HTTP Basic (port 8281) or Digest (port 8282) authentication. If the correct credentials (username: asankha / password: adroitlogic) is presented, the user is shown a response as shown below.
Configuring Basic Authentication
Basic authentication is configured on the HTTP/S transport listener by defining the BasicAuthenticationFilter as a request filter. This causes each request received over this transport to be first passed through this filter, and the authentication credentials validated before being allowed to proceed. The realm name is configured as a property of the filter.
The authentication provider is configured using the standard Spring mechanisms, and maybe based on a simple in-memory list, a database, LDAP or many other mechanisms as supported by Spring Security. In the above example, a simple in-memory implementation is used with the usernames, passwords and roles described inline. The password maybe provided as an encrypted hash (See commented section), or encrypted using techniques described in the article Securing Configurations
Configuring Digest Authentication
Digest authentication is configured similarly to Basic authentication as follows using the DigestProcessingFilter. See above for more details.
The Proxy service secured with Basic and/or Digest authentication - [Path A and Path B]
This is the "rest-mock" proxy service that responds with the authenticated username, roles and the HTTP method, URI and query parameters of the request. By specifying one or more transport ID's a proxy maybe exposed over one or more transports. In this example, the same service is exposed over transports defined as "http-8281" and "http-8282" which was configured in the previous sections to use HTTP Basic and Digest authentication respectively.
To test this service, point your browser at URL [http://localhost:8281/service/rest-mock] - Path A, or [http://localhost:8282/service/rest-mock] - Path B. Your browser will request for the credentials, and you will be presented with the expected response after successful authentication if the correct credentials asankha/adroitlogic is presented.
Proxy Services performing authentication on behalf of users
Basic Authentication - [Path C and Path F]
This configuration defines the credentials to perform a non-preemptive basic authentication against the backend service, only if requested by the service. When using basic authentication, using pre-emptive authentication (described next) will usually allow better performance where the authentication requirements are already known.
Pre-emptive Basic authentication - [Path C and Path E]
Basic authentication maybe pre-emptively performed by the UltraESB on behalf of a client request in either of two ways. The example above depicts how pre-emptive basic authentication maybe added to a message within the mediation code. To test this service, point your browser at URL [http://localhost:8280/service/preemptive-basic-auth-proxy-1]. The request will be pre-emptively authenticated by the UltraESB, and thus you will be presented with the expected response after successful authentication.
The above example depicts how pre-emptive basic authentication maybe performed by specifying credentials specified as properties of a destination endpoint. This method could be used to specify basic, digest or Amazon S3 authentication credentials at the destination endpoint level. To test this service, point your browser at URL [http://localhost:8280/service/preemptive-basic-auth-proxy-2]. The request will be pre-emptively authenticated by the UltraESB, and thus you will be presented with the expected response after successful authentication.
Digest authentication - [Path C and Path G]
Digest authentication credentials could be supplied in the same manner as credentials supplied for Basic authentication in the last section. The Commented code line numbers 6-7 shows how they could be specified programmatically, and the lines 12-13 depicts how they could be provided at the destination endpoint level.
Amazon S3 authentication - [Path C and Path D]
The example above has intentionally been made to read the Amazon S3 credentials of the user from the system environment variables "AWS_S3_USERNAME" and "AWS_S3_PASSWORD" for security reasons. However these maybe easily specified in-line as per previous examples, and optionally encrypted in the configuration.
To upload a file to your Amazon S3 account using the above proxy service, change the destination endpoint URL to your own S3 account, add message properties "transport.auth.username" and "transport.auth.password" as your Amazon S3 AWS Key and Secret Key. You may now upload a text file using the SOA ToolBox as follows.
Set the URL to "http://localhost:8280/service/s3-auth-proxy/test.txt", HTTP method to "PUT", Context type to "text/plain" and the payload body to say "Hello Amazon S3 from UltraESB". Pressing the "Send" button will now yield a successful response as shown below.
To read the file just stored again from Amazon S3, request for the URL "http://localhost:8280/service/s3-auth-proxy/test.txt" from your browser or the ToolBox, and you could see the content that was just stored in the previous step. Using the ToolBox you could use the REST methods GET, DELETE and PUT etc, to retrieve, delete or update this content. A GET request from the SOA ToolBox will receive a response as follows:
NTLM authentication - [Path C and Path H]
The above example is for illustration only, and shows the authentication against a page secured with NTLM authentication
Related Topics and Extension
The UltraESB could easily be configured to accept or send messages over any of its supported transports such as HTTP/S, FTP/S, SFTP, File, Email (POP3/IMAP), MLLP/S or JMS etc. Thus one could easily write a proxy service that may fetch a file from an SFTP location on a given CRON schedule, and post it to Amazon S3 using the S3 authentication, or to accept a REST request with Digest authentication and send an email message of the request using SMTP etc. In addition, you may configure authentication against any Spring Security supported backend service such as an in-memory list, Database, LDAP or custom implementation etc.
WS-Security Username Token Authentication
WS-Security based Username Token authentication is not discussed in this article, but is supported by the UltraESB with its WS-Security support. See relevant sections for more details.
The UltraESB supports XACML authorization to allow fine grained access control. See documentation on the XACML support for more information.