Implement Microsoft Entra ID-based authentication in an AWS Blu Age modernized mainframe application
Vishal Jaswani and Rimpy Tewani, Amazon Web Services
Summary
Mainframe applications that are modernized by using refactoring patterns, such as those by AWS Mainframe Modernization Refactor with AWS Blu Age, require careful integration of authentication mechanisms into the new application architecture. This integration is typically addressed as a post-modernization activity. The task can be complex and often involves the migration or externalization of existing authentication systems to align with modern security standards and cloud-native practices. Developers need to consider how to implement authentication effectively while they work within the constraints of the modernized application's runtime environment and libraries. After modernization, AWS provides ways to make it easier for you to integrate your AWS Blu Age modern code with identity and access management systems such as Amazon Cognito and Microsoft Entra ID
This pattern explains how to implement an authentication mechanism in your modernized application when the authentication provider is Microsoft Entra ID, without spending time on research and trials. The pattern provides:
Field-tested and relevant Angular libraries from the Microsoft Authentication Library (MSAL) and other Microsoft Entra ID documentation that are essential to the authentication implementation.
Configurations required on the AWS Blu Age Runtime to enable Spring Security by using OAuth 2.0.
A library that captures authenticated users’ identities and passes them to the AWS Blu Age Runtime.
Security measures that we recommend implementing.
Troubleshooting tips for commonly encountered problems with the Microsoft Entra ID setup.
Note
This pattern uses the AWS Blu Age OAuth extension library, which is provided to customers as part of their AWS Professional Services
Prerequisites and limitations
Prerequisites
A modernized application that was produced by AWS Blu Age mainframe modernization refactoring tools. This pattern uses CardDemo
as a sample open source mainframe application. The AWS Blu Age OAuth extension library, which is provided by the AWS Blu Age team during your engagement with AWS Professional Services
. An active AWS account to deploy and test the modernized application.
Familiarity with AWS Blu Age configuration files and Microsoft Entra ID fundamentals.
Limitations
This pattern covers OAuth 2.0 authentication and basic token-based authorization flows. Advanced authorization scenarios and fine-grained access control mechanisms are not in scope.
Some AWS services aren’t available in all AWS Regions. For Region availability, see AWS services by Region
. For specific endpoints, see Service endpoints and quotas, and choose the link for the service.
Product versions
This pattern was developed by using:
AWS Blu Age Runtime version 4.1.0 (the pattern also works with later versions that are backward compatible)
MSAL library version 3.0.23
Java Development Kit (JDK) version 17
Angular version 16.1
Architecture
Source technology stack
In typical mainframe environments, authentication is implemented through user profiles. These profiles identify users to the system, define who can sign in, and specify which functions users can perform on system resources. User profiles are managed by security officers or security administrators.
Target technology stack
Microsoft Entra ID
Modernized Java Spring Boot-based backend
AWS Blu Age Runtime
Spring Security with OAuth 2.0
Angular single-page application (SPA)
Target architecture
AWS Blu Age runtime supports OAuth 2.0-based authentication by default, so the pattern uses that standard to protect backend APIs.
The following diagram illustrates the process flow.
Note
The diagram includes Amazon Aurora as an example of database modernization although Aurora isn’t included in the steps for this pattern.

where:
A user tries to authenticate with Microsoft Entra ID.
Microsoft Entra ID returns refresh, access, and ID tokens that the application uses in subsequent calls.
The MSAL interceptor includes the access token in the
Authorization
header of an HTTPS request to call the AWS Blu Age Runtime.The AWS Blu Age
extension-oauth
library extracts the user information from the header by using an AWS Blu Age Runtime configuration file (application-main.yml
) and places this information in aSharedContext
object so that the business logic can consume it.Note
SharedContext
is a runtime component provided by AWS Blu Age that manages application context and state information across the modernized application. For more information about AWS Blu Age Runtime components and updates, see AWS Blu Age release notes in the AWS Mainframe Modernization documentation. For more information about theapplication-main.yml
file, see Set up configuration for AWS Blu Age Runtime in the AWS Mainframe Modernization documentation.The AWS Blu Age Runtime checks if the token is present.
If the token is present, it checks the validity of the token by communicating with Microsoft Entra ID.
If the token isn’t present, the AWS Blu Age Runtime returns an error with HTTP status code 403.
If the token is valid, the AWS Blue Age Runtime allows the business logic to continue. If the token is invalid, the AWS Blu Age Runtime returns an error with HTTP status code 403.
OAuth 2.0 workflow
For a high-level diagram of the OAuth 2.0 workflow, see the Microsoft Entra documentation
Tools
AWS services
AWS Mainframe Modernization provides tools and resources to help you plan and implement migration and modernization from mainframes to AWS managed runtime environments. You can use this service’s refactoring features, which are provided by AWS Blu Age, to convert and modernize your legacy mainframe applications.
Code repository
The CardDemo application has been updated to demonstrate integration with Microsoft Entra ID. You can access the code from the GitHub repository for this pattern
Backend configuration
This pattern requires changes to the application-main.yml
configuration file to enable Spring Security by using OAuth 2.0 on the backend application. The .yml
file looks like this:
gapwalk-application.security: enabled gapwalk-application: security: identity: oauth issuerUri: ${issuerUrl} claim: claims: - claimName: upn claimMapValue: username spring: autoconfigure: exclude: - org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration - org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration security: oauth2: client: registration: azure: client-id: {clientId} client-secret: ${clientSecret} provider: azure authorization-grant-type: authorization_code redirect-uri: ${redirectUri} scope: openid provider: azure: authorization-uri: ${gapwalk-application.security.issuerUri}/oauth2/v2.0/authorize token-uri: ${gapwalk-application.security.issuerUri}/oauth2/v2.0/token jwk-set-uri: ${gapwalk-application.security.issuerUri}/discovery/v2.0/keys resourceserver: jwt: jwk-set-uri: ${gapwalk-application.security.issuerUri}/discovery/v2.0/keys
AWS Blu Age OAuth extension filter library
The AWS Blu Age OAuth extension library is provided by the AWS Blu Age team during your engagement with AWS Professional Services
This library reads the claim.claims
configuration in the application-main.yml
fie that’s shown in the previous code block. This configuration is a list. Each item in the list provides two values: claimName
and claimMapValue
. claimName
represents a key name in a JSON Web Token (JWT) sent by the frontend, and claimMapValue
is the name of the key in SharedContext
. For example, if you want to capture the user ID on the backend, set claimName
to the key name in the JWT that holds the userId
that’s provided by Microsoft Entra ID, and set claimMapValue
to the key name to fetch the user ID in the backend code.
For example, if you set UserId
in claimMapValue
, you can use the following code to extract the user ID:
SharedContext.get().getValue("userId", [UserId]);
Best practices
In your implementation of this pattern, take the following important security considerations into account.
Important
This pattern provides a foundation for authentication integration. We recommend that you implement security measures in addition to those discussed in this section based on your business requirements before you deploy it to production.
AWS configuration security. Move sensitive configuration values from
application-main.yml
to AWS Secrets Manager. For example, configure the following properties by using Secrets Manager:security: oauth2: client: registration: azure: client-id: {clientId} client-secret: ${clientSecret}
For more information about how you can use Secrets Manager to configure AWS Blu Age parameters, see AWS Blu Age Runtime secrets in the AWS Mainframe Modernization documentation.
Runtime environment protection. Configure the modernized application environment with proper AWS security controls:
server: tomcat: remoteip: protocol-header: X-Forwarded-Proto remote-ip-header: X-Forwarded-For forward-headers-strategy: NATIVE
Amazon CloudWatch logging. Consider adding the file
logback-spring.xml to src/main/resources
:<configuration> <appender name="CLOUDWATCH" class="com.amazonaws.services.logs.logback.CloudWatchAppender"> <logGroup>/aws/bluage/application</logGroup> <logStream>${AWS_REGION}-${ENVIRONMENT}</logStream> <layout> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> </layout> </appender> <root level="INFO"> <appender-ref ref="CLOUDWATCH"/> </root> </configuration>
For information about enabling tracing with CloudWatch, see Enable trace to log correlation in the CloudWatch documentation.
Token configuration and handling. Configure token lifetimes in Microsoft Entra ID to align with your security requirements. Set access tokens to expire within 1 hour and refresh tokens to expire within 24 hours. In the AWS Blu Age Runtime configuration (
application-main.yml
), make sure that JWT validation is configured properly with the exact issuer URI and audience values from your Entra ID application registration.When a token expires and is refreshed:
The Angular application's error interceptor handles the 401 response by obtaining a new token through MSAL.
The new token is sent with the subsequent request.
The AWS Blu Age Runtime's OAuth filter validates the new token and automatically updates
SharedContext
with the current user information. This ensures that business logic continues to have access to valid user context throughSharedContext.get().getValue()
calls.
For more information about the AWS Blu Age Runtime components and their updates, see AWS Blu Age release notes.
AWS Blu Age Runtime security. The
oauth2-ext
library provided by AWS Blu Age must be placed in the correct shared directory location ({app-server-home}/shared/
) with proper file permissions. Verify that the library successfully extracts user information from JWTs by checking theSharedContext
object population in your logs.Specific claims configuration. In
application-main.yml
, define the claims that you need from Microsoft Entra ID explicitly. For example, to capture the user's email and roles, specify:gapwalk-application: security: claim: claims: - claimName: upn claimMapValue: username - claimName: roles claimMapValue: userRoles - claimName: email claimMapValue: userEmail
Error handling. Add error handling to address authentication failures in your Angular application; for example:
@Injectable() export class AuthErrorInterceptor implements HttpInterceptor { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(request).pipe( catchError((error: HttpErrorResponse) => { if (error.status === 401) { // Handle token expiration this.authService.login(); } if (error.status === 403) { // Handle unauthorized access this.router.navigate(['/unauthorized']); } return throwError(() => error); }) ); } }
Session timeout configuration. Configure session timeout settings in both the AWS Blu Age Runtime and Microsoft Entra ID. For example, add the following code to your
application-main.yml
file:server: servlet: session: timeout: 3600 # 1 hour in seconds
MsalGuard. You must implement the MsalGuard feature for all protected routes to prevent unauthorized access. For example:
const routes: Routes = [ { path: '', redirectTo: '/transaction-runner', pathMatch: 'full' }, { path: 'transaction-runner', component: TransactionRunnerComponent, canActivate:guards }, { path: 'user-info', component: UserInfoComponent, canActivate:guards }, { path: 'term/:transid/:commarea', component: TermComponent, canActivate:guards }, { path: 'code', component: TransactionRunnerComponent } ];
Routes that don’t have MsalGuard protection will be accessible without authentication, potentially exposing sensitive functionality. Make sure that all routes that require authentication include the guards in their configuration.
Epics
Task | Description | Skills required |
---|---|---|
Set up a Microsoft Azure account to create an Entra ID. | For options and instructions, see the Microsoft Azure website | App developer |
Set up a Microsoft Entra ID in your application. | To learn how to add Microsoft Entra ID B2C (Azure AD B2C) authentication to your Angular SPA, see the Microsoft documentation
| App developer |
Task | Description | Skills required |
---|---|---|
Clone the GitHub repository to get the Angular code required for authentication. | Run the following command to clone the GitHub repository
| App developer |
Deploy the AWS Blu Age modernized code on a Tomcat server to implement authentication. | To set up the local environment that includes Tomcat and the Angular development server, follow the installation steps provided by the AWS Blu Age team as part of your customer engagement with AWS Professional Services. | App developer |
Task | Description | Skills required |
---|---|---|
Enable AWS Blu Age Runtime security to protect the AWS Blu Age REST API endpoints. | Configure the
| App developer |
Incorporate the example code from your local environment into your Blu Age modernized Angular code base. | For information about how to incorporate the example into your AWS Blu Age modernized Angular code base, see the Code repository section earlier in this pattern. | App developer |
Place the | Place the
| App developer |
Task | Description | Skills required |
---|---|---|
Deploy the frontend application. | Run the following commands to start the frontend application locally:
NoteAdding the | App developer |
Start the backend application. | Start Tomcat server in Eclipse. | App developer |
Task | Description | Skills required |
---|---|---|
Test login functionality. | Access the locally deployed application at NoteHTTP is used here for demonstration purposes. In a production or other publicly accessible environment, you must use HTTPS for security. Even for local development, we recommend that you set up HTTPS when possible. The Microsoft login prompt should appear, and users who are configured in Microsoft Entra ID should be allowed to access the application. | App developer |
Test the authorization header in the request. | NoteThe following steps use the CardDemo
| App developer |
Test the logout functionality. | Choose Quit to log out, and try to access the application again. It should present a new login prompt. | App developer |
Troubleshooting
Issue | Solution |
---|---|
The token issued by Microsoft Entra ID isn’t compatible with Spring Boot OAuth 2.0 security. | For a resolution to the issue, see Microsoft Entra ID OAuth Flow |
General token-related questions. | To decode and view the contents of a JWT token, use the https://jwt.io/ |
Related resources
For information about refactoring your application by using AWS Blu Age, see the AWS Mainframe Modernization documentation.
To understand how OAuth 2.0 works, see the OAuth 2.0 website
. For an overview of the Microsoft Authentication Library (MSAL), see the Microsoft Entra documentation
. For information about user profiles on an AS/400 system, see the IBM i (AS400) tutorial
. For the OAuth 2.0 and OpenID Connect (OIDC) authentication flow in the Microsoft identity platform, see the Microsoft Entra documentation
.