June 13, 2019 By Dominic Panarello 4 min read

The login experience is the end user’s first impression of an application. It should be simple to use and—most importantly—error free.

The login experience is the end-user’s first impression of an application. It should be simple to use and—most importantly—error free.

This technical article addresses the latter by detailing Liberty configuration that produces the ideal OAuth2 login experience, using IBM Cloud App ID as an example authentication provider.

Prerequisites and overview

Before reading this article, it is recommended to review the following:

Sample OAuth2 authentication flow

In the above flow, the protected webapp is served by an application server—in this case, Websphere Liberty. The appserver is responsible for handling the redirect to the OAuth2 authentication provider, then the exchange of the user’s authorization_code for OAuth2 authentication tokens (JWT), while additionally establishing login and session cookies as required to maintain a secure state during the process.

If you were to inspect the default cookies created and destroyed during Liberty’s OAuth2 authentication process, you would identify at least the following:

  • WASOidcState*: Authentication cookie containing a once-off state
  • WASReqURLOidc*: Authentication cookie containing the requested application url, for redirect after authentication is successful
  • LTPAToken2: Session cookie for an established authenticated session

*The former two cookies are appended with a randomly generated nonce

Authentication flow timeout

Liberty’s authentication cookies expire by default after just seven minutes, governed by the openidConnectClient property authenticationTimeLimit. These cookies are established when the end-user first requests the protected application URL, as seen in the OAuth2 authentication flow. Functionally, this means that after first attempting to access the application, the end-user has seven minutes to enter their credentials (including invalid attempts) and be redirected back to Liberty.

For example, if they accessed the application home page as an unauthenticated user and waited 10 minutes before successfully entering their valid credentials, Liberty will reply by default with an unfriendly generic 401 or 500 error. The server log would indicate something similar to: 

[ERROR ] CWWKS1750E: A request to [https://localhost:9044/oidcclient/redirect/MyRP] is not valid. 
A required cookie with a name that begins with WASReqURLOidc is missing. 
The host name that is used to access the client might not match the name that is registered at the provider. 
A response code of 500 is returned.

Fundamentally, whenever these cookies have expired, the authentication flow cannot succeed.

To counter this, the authentication time limit should be set to the maximum period that you expect your users to idle during the authentication flow without requesting the protected application URL. App ID’s standard login page, for example, expires after 30 minutes. Therefore, in a simplistic example, an authenticationTimeLimit of “30m” could be reasonable.

However, a distracted user might enter their credentials incorrectly, refresh the login page or otherwise without ever interacting with Liberty. This would require an authentication time limit increase to an hour or two. Note that for security and functional reasons, this limit should remain as low as possible while still supporting your intended use cases.

Session failover on Liberty with OAuth2

If your application is deployed in a highly available environment with more than one application server node, you will need a configuration strategy for session failover. This will improve the experience for end-users in the event a Liberty node were to stop responding.

For example, if any users had an LTPA session token (cookie) issued by LibertyNodeA, which subsequently went offline, a load balancer could direct those users to LibertyNodeB. However, all of those users would automatically be logged out; their LTPA token is not valid on any other Liberty node by default.

We can improve that experience— Liberty does support session failover with OAuth2. This requires very specific openidConnectClient configuration that is not enabled by default:

uniqueUserIdentifier=”sub”
userIdentifier=”sub”
userIdentityToCreateSubject=”sub”
accessTokenInLtpaCookie=”true”
inboundPropagation=”supported”
audiences=”${clientId}”
validationEndpointUrl=”${userInfoEndpoint}”
validationMethod=”userinfo”
userInfoEndpointEnabled=”true”
userInfoEndpointUrl=”${userInfoEndpoint}”

The above configuration achieves two goals: it inserts the OAuth2 access_token into Liberty’s LTPA cookie on LibertyNodeA, while also using the access_token to validate and reconstruct a new LTPA cookie on LibertyNodeB during session failover. When this occurs, the end-user’s request and authenticated session are seamlessly rolled over to the new node – and wouldn’t otherwise be aware except for the destruction and creation of a new LTPA cookie under the covers.

You should be aware of the following caveats:

  • Both Liberty nodes should be configured to accept the same audiences (OAuth2 clientIds).
  • A node could fail at any time for any request. That means all requests should qualify for an openidConnectClient authFilter that is appropriate for your configuration.
  • The provider-issued access_token must contain the accessTokenInLtpaCookie increases the size of the cookie header substantially and your upstream infrastructure, such as Ingress, may need to be reconfigured as such.

Failure to adhere to the above will result in an unsuccessful failover, resulting in the user’s session being terminated with a corresponding message in the server’s console.log.

Error page configuration

It’s worth highlighting that other unforeseen authentication flow errors can occur, even with ideal configuration. For example, the connection between Liberty and the authentication provider could time out during OAuth2 token exchange. In that case, the application will fall back to Liberty’s default 401 unauthorized response. These responses are not user-friendly and typically do not offer a retry or redirect mechanism.

To counter this, as an industry best practice, it is your application’s responsibility to define generic or specific error pages as seen in this example.

A simple first-step recommendation would be to define a generic, “Sorry, something went wrong” page—regardless of the error. This would contain a link back to your application’s home page to restart the authentication process if an authenticated session has not yet been established. This would handle any errors during the final stages of the OAuth2 authentication flow.

Unfortunately, any errors emitted directly from the oidcclient webapp currently cannot be customised; Liberty doesn’t support this at time of writing.

Supplying configuration that limits errors that end-users might encounter

Through an informed understanding of the OAuth2 authentication flow on Liberty, we can supply configuration that limits errors that end-users might encounter. It is important to ensure that the vast majority of use-case scenarios are covered and thoroughly tested in your topology.

In particular, long idle time on login pages and the use of browser navigation buttons (refresh/back) are common use cases but often result in a high frequency of errors in default configurations. Enhanced configuration, together with custom error responses, will deliver a better login experience for all end-users.

Resources

Was this article helpful?
YesNo

More from Cloud

IBM Tech Now: April 8, 2024

< 1 min read - ​Welcome IBM Tech Now, our video web series featuring the latest and greatest news and announcements in the world of technology. Make sure you subscribe to our YouTube channel to be notified every time a new IBM Tech Now video is published. IBM Tech Now: Episode 96 On this episode, we're covering the following topics: IBM Cloud Logs A collaboration with IBM watsonx.ai and Anaconda IBM offerings in the G2 Spring Reports Stay plugged in You can check out the…

The advantages and disadvantages of private cloud 

6 min read - The popularity of private cloud is growing, primarily driven by the need for greater data security. Across industries like education, retail and government, organizations are choosing private cloud settings to conduct business use cases involving workloads with sensitive information and to comply with data privacy and compliance needs. In a report from Technavio (link resides outside ibm.com), the private cloud services market size is estimated to grow at a CAGR of 26.71% between 2023 and 2028, and it is forecast to increase by…

Optimize observability with IBM Cloud Logs to help improve infrastructure and app performance

5 min read - There is a dilemma facing infrastructure and app performance—as workloads generate an expanding amount of observability data, it puts increased pressure on collection tool abilities to process it all. The resulting data stress becomes expensive to manage and makes it harder to obtain actionable insights from the data itself, making it harder to have fast, effective, and cost-efficient performance management. A recent IDC study found that 57% of large enterprises are either collecting too much or too little observability data.…

IBM Newsletters

Get our newsletters and topic updates that deliver the latest thought leadership and insights on emerging trends.
Subscribe now More newsletters