Skip to content

Commit

Permalink
fix(core): Improve saml test connection function (#5899)
Browse files Browse the repository at this point in the history
improve-saml-test-connection return
  • Loading branch information
flipswitchingmonkey authored Apr 4, 2023
1 parent f6bbb94 commit e1a730a
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 19 deletions.
6 changes: 2 additions & 4 deletions packages/cli/src/sso/saml/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ export class SamlUrls {

static readonly initSSO = '/initsso';

static readonly restInitSSO = this.samlRESTRoot + this.initSSO;

static readonly acs = '/acs';

static readonly restAcs = this.samlRESTRoot + this.acs;
Expand All @@ -17,9 +15,9 @@ export class SamlUrls {

static readonly configTest = '/config/test';

static readonly configToggleEnabled = '/config/toggle';
static readonly configTestReturn = '/config/test/return';

static readonly restConfig = this.samlRESTRoot + this.config;
static readonly configToggleEnabled = '/config/toggle';

static readonly defaultRedirect = '/';

Expand Down
16 changes: 12 additions & 4 deletions packages/cli/src/sso/saml/routes/saml.controller.ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import type { PostBindingContext } from 'samlify/types/src/entity';
import { isSamlLicensedAndEnabled } from '../samlHelpers';
import type { SamlLoginBinding } from '../types';
import { AuthenticatedRequest } from '@/requests';
import { getServiceProviderEntityId, getServiceProviderReturnUrl } from '../serviceProvider.ee';
import {
getServiceProviderConfigTestReturnUrl,
getServiceProviderEntityId,
getServiceProviderReturnUrl,
} from '../serviceProvider.ee';

@RestController('/sso/saml')
export class SamlController {
Expand Down Expand Up @@ -100,6 +104,10 @@ export class SamlController {
private async acsHandler(req: express.Request, res: express.Response, binding: SamlLoginBinding) {
const loginResult = await this.samlService.handleSamlLogin(req, binding);
if (loginResult) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (req.body.RelayState && req.body.RelayState === getServiceProviderConfigTestReturnUrl()) {
return res.status(202).send(loginResult.attributes);
}
if (loginResult.authenticatedUser) {
// Only sign in user if SAML is enabled, otherwise treat as test connection
if (isSamlLicensedAndEnabled()) {
Expand Down Expand Up @@ -134,11 +142,11 @@ export class SamlController {
*/
@Get(SamlUrls.configTest, { middlewares: [samlLicensedOwnerMiddleware] })
async configTestGet(req: AuthenticatedRequest, res: express.Response) {
return this.handleInitSSO(res);
return this.handleInitSSO(res, getServiceProviderConfigTestReturnUrl());
}

private async handleInitSSO(res: express.Response) {
const result = this.samlService.getLoginRequestUrl();
private async handleInitSSO(res: express.Response, relayState?: string) {
const result = this.samlService.getLoginRequestUrl(relayState);
if (result?.binding === 'redirect') {
return result.context.context;
} else if (result?.binding === 'post') {
Expand Down
28 changes: 17 additions & 11 deletions packages/cli/src/sso/saml/saml.service.ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import {
setSamlLoginLabel,
updateUserFromSamlAttributes,
} from './samlHelpers';
import type { Settings } from '../../databases/entities/Settings';
import type { Settings } from '@/databases/entities/Settings';
import axios from 'axios';
import https from 'https';
import type { SamlLoginBinding } from './types';
import type { BindingContext, PostBindingContext } from 'samlify/types/src/entity';
import { validateMetadata, validateResponse } from './samlValidator';
import { getInstanceBaseUrl } from '@/UserManagement/UserManagementHelper';

@Service()
export class SamlService {
Expand All @@ -48,6 +49,7 @@ export class SamlService {
loginLabel: 'SAML',
wantAssertionsSigned: true,
wantMessageSigned: true,
relayState: getInstanceBaseUrl(),
signatureConfig: {
prefix: 'ds',
location: {
Expand Down Expand Up @@ -92,36 +94,40 @@ export class SamlService {
return getServiceProviderInstance(this._samlPreferences);
}

getLoginRequestUrl(binding?: SamlLoginBinding): {
getLoginRequestUrl(
relayState?: string,
binding?: SamlLoginBinding,
): {
binding: SamlLoginBinding;
context: BindingContext | PostBindingContext;
} {
if (binding === undefined) binding = this._samlPreferences.loginBinding ?? 'redirect';
if (binding === 'post') {
return {
binding,
context: this.getPostLoginRequestUrl(),
context: this.getPostLoginRequestUrl(relayState),
};
} else {
return {
binding,
context: this.getRedirectLoginRequestUrl(),
context: this.getRedirectLoginRequestUrl(relayState),
};
}
}

private getRedirectLoginRequestUrl(): BindingContext {
const loginRequest = this.getServiceProviderInstance().createLoginRequest(
this.getIdentityProviderInstance(),
'redirect',
);
private getRedirectLoginRequestUrl(relayState?: string): BindingContext {
const sp = this.getServiceProviderInstance();
sp.entitySetting.relayState = relayState ?? getInstanceBaseUrl();
const loginRequest = sp.createLoginRequest(this.getIdentityProviderInstance(), 'redirect');
//TODO:SAML: debug logging
LoggerProxy.debug(loginRequest.context);
return loginRequest;
}

private getPostLoginRequestUrl(): PostBindingContext {
const loginRequest = this.getServiceProviderInstance().createLoginRequest(
private getPostLoginRequestUrl(relayState?: string): PostBindingContext {
const sp = this.getServiceProviderInstance();
sp.entitySetting.relayState = relayState ?? getInstanceBaseUrl();
const loginRequest = sp.createLoginRequest(
this.getIdentityProviderInstance(),
'post',
) as PostBindingContext;
Expand Down
5 changes: 5 additions & 0 deletions packages/cli/src/sso/saml/serviceProvider.ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export function getServiceProviderReturnUrl(): string {
return getInstanceBaseUrl() + SamlUrls.restAcs;
}

export function getServiceProviderConfigTestReturnUrl(): string {
return getInstanceBaseUrl() + SamlUrls.configTestReturn;
}

// TODO:SAML: make these configurable for the end user
export function getServiceProviderInstance(prefs: SamlPreferences): ServiceProviderInstance {
if (serviceProviderInstance === undefined) {
Expand All @@ -24,6 +28,7 @@ export function getServiceProviderInstance(prefs: SamlPreferences): ServiceProvi
wantAssertionsSigned: prefs.wantAssertionsSigned,
wantMessageSigned: prefs.wantMessageSigned,
signatureConfig: prefs.signatureConfig,
relayState: prefs.relayState,
nameIDFormat: ['urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'],
assertionConsumerService: [
{
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/sso/saml/types/samlPreferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ export class SamlPreferences {
action: 'after',
},
};

@IsString()
@IsOptional()
relayState?: string = '';
}

0 comments on commit e1a730a

Please sign in to comment.