Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix to work with apiml customized token name in v2 #573

Open
wants to merge 1 commit into
base: v2.x/staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
All notable changes to the Zlux Server Framework package will be documented in this file..
This repo is part of the app-server Zowe Component, and the change logs here may appear on Zowe.org in that section.

## 2.18.1
- Fix: Server would not work when API Gateway token name was customized (#574)

## 2.17.0
- Enhancement: Added function `isClientAttls(zoweConfig)` within `libs/util.js`. Whenever a plugin makes a network request, it should always use this to determine if a normally HTTPS request should instead be made as HTTP due to AT-TLS handling the TLS when enabled. (#544)
- Bugfix: Fixed function `isServerAttls(zoweConfig)` within `libs/util.js`, which was preventing using AT-TLS with app-server. (#544)
Expand Down
36 changes: 20 additions & 16 deletions plugins/sso-auth/lib/apimlHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const zluxUtil = require('../../../lib/util');
*/
const DEFAULT_EXPIRATION_MS = 29700000;
const TOKEN_NAME = 'apimlAuthenticationToken';
const TOKEN_LENGTH = TOKEN_NAME.length;

function readUtf8FilesToArray(fileArray) {
var contentArray = [];
Expand Down Expand Up @@ -56,7 +55,12 @@ function readUtf8FilesToArray(fileArray) {

class ApimlHandler {
constructor(pluginDef, pluginConf, componentConf, context, zoweConf) {
this.logger = context.logger;
this.logger = context.logger;
if (zoweConf.zowe.cookieIdentifier && (zoweConf.components.gateway?.apiml?.security?.auth?.uniqueCookie === true)) {
this.tokenName = `${TOKEN_NAME}.${zoweConf.zowe.cookieIdentifier}`;
} else {
this.tokenName = TOKEN_NAME;
}
this.apimlConf = componentConf.node.mediationLayer.server;
this.gatewayUrl = `https://${this.apimlConf.gatewayHostname}:${this.apimlConf.gatewayPort}`;
this.isHttps = !zluxUtil.isClientAttls(zoweConf);
Expand All @@ -72,7 +76,7 @@ class ApimlHandler {

logout(request, sessionState) {
return new Promise((resolve, reject) => {
if (!(request.cookies && request.cookies[TOKEN_NAME])) {
if (!(request.cookies && request.cookies[this.tokenName])) {
return resolve({success: true});
}
const gatewayUrl = this.gatewayUrl;
Expand All @@ -83,7 +87,7 @@ class ApimlHandler {
path: '/apicatalog/api/v1/auth/logout',
method: 'POST',
headers: {
'apimlAuthenticationToken': request.cookies[TOKEN_NAME]
'apimlAuthenticationToken': request.cookies[this.tokenName]
},
agent: this.httpsAgent
}
Expand All @@ -94,7 +98,7 @@ class ApimlHandler {
res.on('end', () => {
let apimlCookie;
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve({ success: true, cookies: [{name:TOKEN_NAME,
resolve({ success: true, cookies: [{name:this.tokenName,
value:'non-token',
options: {httpOnly: true,
secure: true,
Expand Down Expand Up @@ -153,7 +157,7 @@ class ApimlHandler {
resolve({success: false}); // return the object directly
});
});
} else if (request.cookies && request.cookies[TOKEN_NAME]) {
} else if (request.cookies && request.cookies[this.tokenName]) {
return this.authenticateViaCookie(request, sessionState);
} else {
return Promise.resolve({success: false});
Expand All @@ -162,8 +166,8 @@ class ApimlHandler {

authenticateViaCookie(request, sessionState) {
return new Promise((resolve, reject)=> {
this.logger.debug(`Authenticate with cookie`,TOKEN_NAME);
this.queryToken(request.cookies[TOKEN_NAME]).then(data=> {
this.logger.debug(`Authenticate with cookie`,this.tokenName);
this.queryToken(request.cookies[this.tokenName]).then(data=> {
let expiration;
const expirationDate = new Date(data.expiration);
const creationDate = new Date(data.creation);
Expand All @@ -177,7 +181,7 @@ class ApimlHandler {
this.doLogin(request, sessionState, true).then(result=> resolve(result))
.catch(e => reject(e));
} else {
this.setState(request.cookies[TOKEN_NAME],
this.setState(request.cookies[this.tokenName],
data.userId, sessionState);
resolve({success: true, username: sessionState.username, expms: expiration});
}
Expand Down Expand Up @@ -230,7 +234,7 @@ class ApimlHandler {
return new Promise((resolve, reject) => {
const options = this.makeOptions('/gateway/api/v1/auth/query',
'GET',
TOKEN_NAME+'='+token);
this.tokenName+'='+token);

let data = [];
this.logger.debug(`Sending query token request to path=${options.path}`);
Expand Down Expand Up @@ -283,9 +287,9 @@ class ApimlHandler {
if (typeof res.headers['set-cookie'] === 'object') {
for (const cookie of res.headers['set-cookie']) {
const content = cookie.split(';')[0];
let index = content.indexOf(TOKEN_NAME);
let index = content.indexOf(this.tokenName);
if (index >= 0) {
token = content.substring(index+1+TOKEN_LENGTH);
token = content.substring(index+1+this.tokenName.length);
}
}
}
Expand All @@ -305,7 +309,7 @@ class ApimlHandler {
if (expiration > 0) {
this.setState(token, data.userId, sessionState);
resolve({ success: true, username: sessionState.username, expms: expiration,
cookies: [{name:TOKEN_NAME, value:token, options: {httpOnly: true, secure: true}}]});
cookies: [{name:this.tokenName, value:token, options: {httpOnly: true, secure: true}}]});
} else {
resolve({ success: false, reason: 'Unknown'});
}
Expand Down Expand Up @@ -371,7 +375,7 @@ class ApimlHandler {
authorized(request, sessionState) {
if (sessionState.authenticated) {
request.username = sessionState.username;
request.ssoToken = request.cookies[TOKEN_NAME];
request.ssoToken = request.cookies[this.tokenName];
return Promise.resolve({ authenticated: true, authorized: true });
} else {
return Promise.resolve({ authenticated: false, authorized: false });
Expand All @@ -382,15 +386,15 @@ class ApimlHandler {
if (!sessionState.apimlToken) {
return;
}
// req2Options.headers[TOKEN_NAME] = sessionState.apimlToken;
// req2Options.headers[this.tokenName] = sessionState.apimlToken;
if (this.usingSso) {
req2Options.headers['Authorization'] = 'Bearer '+sessionState.apimlToken;
}
}

restoreSessionState(request, sessionState) {
return new Promise((resolve, _reject) => {
const token = request.cookies[TOKEN_NAME];
const token = request.cookies[this.tokenName];
if (!token) {
sessionState.authenticated = false;
resolve({success: false});
Expand Down
Loading