52 lines
2.5 KiB
TypeScript
52 lines
2.5 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
import { Guid } from '@common/types/guid';
|
|
import * as pk from 'pako';
|
|
|
|
@Injectable()
|
|
export class SamlLoginService {
|
|
|
|
constructor() {}
|
|
|
|
buildRelayState(spId: string, configurableLoginId: string): string {
|
|
let uri = 'spId=' + spId;
|
|
uri += '&configurableLoginId=' + configurableLoginId;
|
|
return encodeURIComponent(uri);
|
|
}
|
|
|
|
resolveConfigurableLoginId(relayState: string): string {
|
|
const decoded = decodeURIComponent(relayState);
|
|
const routeParams = new URLSearchParams(decoded);
|
|
return routeParams.has('configurableLoginId') ? routeParams.get('configurableLoginId') : undefined;
|
|
}
|
|
resolveSpId(relayState: string): string {
|
|
const decoded = decodeURIComponent(relayState);
|
|
const routeParams = new URLSearchParams(decoded);
|
|
return routeParams.has('spId') ? routeParams.get('spId') : '';
|
|
}
|
|
|
|
getSamlLoginUrl(spEntityID: string, idpUrl: string, binding: string, assertionConsumerServiceUrl: string, configurableLoginId: string) {
|
|
const now = new Date();
|
|
let protocolBinding = '';
|
|
switch (binding) {
|
|
case "Redirect": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" '; break;
|
|
case "Artifact": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" '; break;
|
|
case "Post": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" '; break;
|
|
}
|
|
const authenticationRequest = '<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_' + Guid.create() + '" Version="2.0" ' +
|
|
'IssueInstant="' + now.toISOString() + '" ' +
|
|
protocolBinding +
|
|
'AssertionConsumerServiceUrl="' + assertionConsumerServiceUrl + '" ' +
|
|
'Destination="' + idpUrl + '">' +
|
|
'<saml2:Issuer>' + spEntityID + '</saml2:Issuer>' +
|
|
'</saml2p:AuthnRequest>';
|
|
const uint = new Uint8Array(authenticationRequest.length);
|
|
for (let i = 0, j = authenticationRequest.length; i < j; ++i) {
|
|
uint[i] = authenticationRequest.charCodeAt(i);
|
|
}
|
|
const base64String = btoa(pk.deflateRaw(uint, { to: 'string' }));
|
|
const relayState = this.buildRelayState(spEntityID, configurableLoginId);
|
|
const url = idpUrl + '?RelayState=' + relayState + '&SAMLRequest=' + encodeURIComponent(base64String);
|
|
return url;
|
|
}
|
|
|
|
} |