Security Global Forum

 View Only

HTTP Header Authentication with IBM Security Verify Access

By Shane Weeden posted Mon November 29, 2021 12:53 AM

  

HTTP Header Authentication in IBM Security Verify Access


As part of a couple of different technical solutions investigations with IBM Security Verify Access (ISVA) I've had cause to want to be able to authenticate to the Web Reverse Proxy (WRP) via a custom HTTP header, without sending any redirects back to the client as part of the authentication process. There are several scenarios where this can be useful including when an upstream trusted proxy has already authenticated and asserted user identity, or for processing cryptographically generated material that is transmitted by the client in a HTTP header (e.g. authentication via a JWT in a header).

ISVA already has a built-in use case for authentication and session management via HTTP header, that being for OAuth bearer tokens when using oauth-auth for authentication. This topic has been covered in previous articles including this one from Philip Nye, and also in the configuration of mobile multi-factor authentication using IBM Verify. See the MMFA Cookbook for a detailed tutorial on this topic.

In the case of oauth-auth, the WRP has very specific code in place that checks for the Authorization header, with the value of the header requiring a prefix of 'Bearer '. That technique cannot easily be generalised to authentication via the value of any HTTP header. It turns out however that authentication can be achieved using any HTTP header provided in a request by creatively combining several other capabilities of ISVA.

This article will take you through the setup of such a scenario, explaining how the features are combined to provide to the solution. For the purposes of demonstration, our "client" will be curl, and the HTTP header that will be used for authentication processing will be just a straight assertion of the username, such as:
the-user-is: testuser

The WRP will be configured to require authenticated access to the built-in cred-viewer local application, and success will be measured by the result of the following curl command returning credential attributes for testuser:
curl -k -i --max-redirs 0 \ 
-H "Accept: application/json" \
-H "the-user-is: testuser" \
https://www.myidp.ibm.com/ivcreds

Note that '-k' is used because my test WRP is using the default self-signed certificate. Try the curl command on a freshly created WRP and you should get back a 200 response with the body:
{ "operation" : "login" }
 This is essentially the JSON version of the login page.

Solution Configuration

WRP Configuration


If not already completed, use the wizard to configure your reverse proxy for AAC authentication.



The rest of the required WRP configuration changes are made by editing the WRP configuration file.

Make sure the cred-viewer local application is enabled, at the target url /ivcreds.
More can be read about this in my article on this application:
[local-apps]
cred-viewer = ivcreds

Next, we want to avoid having the WRP send back the 200 with the login operation. This means we need something else to process the request, and for that we are going to use an advanced access control (AAC) InfoMap. There are plenty of existing articles on InfoMap authentication, including this introduction to InfoMap. In order for the WRP to provide the request to AAC InfoMap, we are going to combine two other features - local response direct (LRR), and internal redirects (aka follow-redirects-for).

Local response redirect instructs WebSEAL to redirect to another URL for processing of certain types of requests such as authentication challenges, or error pages. The feature is self-documented in the WRP configuration file. Our configuration for LRR is going to focus only on sending the login authentication challenge to an external source, which in our case is going to be an AAC authentication policy. This is done with the following WRP configuration:
[acnt-mgt]
enable-local-response-redirect = yes

[local-response-redirect]
local-response-redirect-uri = [login] /mga/sps/authsvc/policy/headerauthn

Finally we do not want this redirect being sent back to the client (curl in our case, but could also be a browser) and therefore we leverage internal redirects with the following configuration:
[server] 
maximum-followed-redirects = 2
follow-redirects-for = !LRR!
The setting of at least 2 for maximum-follow-redirects warrants some further explanation. Two redirects need to be automatically followed for this scenario. The first is a redirect to the authentication policy as a result of the local-response-redirect settings for replacing the login page, and the second is the redirect to the originally protected resource after authentication is completed by the InfoMap authentication policy.

AAC configuration

This scenario recommends the path-based policy URI kickoff method for AAC authentication policy. Set the following advanced configuration property (a value of "path" or "both" would work):
sps.authService.policyKickoffMethod = path
Next create a mapping rule for the InfoMap policy. The following example is the bare-bones minimum required to make things work assuming a well-formed request. A real implementation should include error checking to see if the header is actually present and return a sensible error page if not. 
context.set(Scope.SESSION, 
"urn:ibm:security:asf:response:token:attributes",
"username",
context.get(Scope.REQUEST, "urn:ibm:security:asf:request:header", "the-user-is"));

success.setValue(true);




Create an authentication mechanism using this mapping rule (no page template required), and an authentication policy that leverages only this mechanism.





Deploy all pending changes, and the solution should be ready for testing:
$ curl -k -i --max-redirs 0 -H "Accept: application/json" -H "the-user-is: testuser" https://www.myidp.ibm.com/ivcreds 

HTTP/1.1 200 OK
content-length: 1273
content-type: application/json
date: Mon, 29 Nov 2021 03:26:13
GMT p3p: CP="NON CUR OTPi OUR NOR UNI"
cache-control: no-cache strict-transport-security: max-age=31536000; includeSubDomains
Set-Cookie: AMWEBJCT!%2Fmga!JSESSIONID=0000sU7PGMjMXoI9FUsYs2NOv8U:6fc39fa6-ac1c-4b8b-9e04-0ccefdb2cbfd; Path=/; Secure; HttpOnly Set-Cookie: PD-S-SESSION-ID=1_2_1_xTb5o6q7sDJ+Fy52kOIgqhbCws0Vy-L3Ow3Cf95UO-ZoBKHl; Path=/; Secure; HttpOnly

{
... abbreviated ...,
"AZN_CRED_PRINCIPAL_NAME":"testuser"
}

Notice that the response received at the client is the originally protected resource after authentication for testuser has successfully completed! You should also be able to try this for the administrative sec_master user, or any other user account, and see a similar output.

Other considerations

Session Management


This technique allows the authentication of a request based entirely on the data in HTTP headers, and potentially other attributes of the request. Ideally, we don't want to have to go through the process of calling out to an AAC InfoMap authentication policy for every request, as this is somewhat inefficient, resulting in the establishment of a new HTTP session every time. You will notice in the successful curl response above that a PD-S-SESSION-ID cookie is returned. If the actual client is a browser-based application, or another type of client capable of cookie-based session management, then the session cookie will be used for subsequent requests and take priority over HTTP headers since the WRP login process will not be initiated. If cookie-based session management is not suitable for the nature of the client being used, then be careful about employing alternative session management functionality such as session-http-headers as the value of the HTTP header should be unique per-session and consistent for the entire expected lifetime of that session. For example using a username as the session index as shown in this example would generally be bad as there could be multiple sessions for the same user and the WRP would not treat these separately. Bottom line - use the session cookie management when possible.

Error Handling


The example shown here has zero consideration for error handling. At the very least the InfoMap should deal with the scenario where the expected HTTP header is not present. This could result in an error page template being returned, or a redirect to an alternative authentication process.

Final Thoughts

When I sat down to first investigate this idea of HTTP header authentication in WRP, I wasn't sure it was possible. I first reflected on the very old software version of the product which allowed (and encouraged) the development of C/C++ shared library plugins to (what was then) WebSEAL. I know HTTP header authentication was possible with such a library, and back in the early 2000's, that was how things were done. Many customer core files later, mostly as a result of memory management or thread safety issues, we now have a very different approach to integrations. Things have become much more stable too.

For a while I thought this may have come at the expense of not being able to achieve generic HTTP header authentication at all. It turns out though that a wealth of other features that have been added to the WRP since then. The novel combination of EAI authentication (via AAC authentication policies - in this case with InfoMap), local response redirect, and internal redirects allows us to achieve the seemingly difficult quite easily and very extensibly. In my own experimentation I've even done a more advanced InfoMap that permits validation of OAuth DPoP headers using the ISVA Federation STS for JWT validation. I wonder what the next ISVA investigation will reveal.
0 comments
40 views

Permalink