Skip to content

Commit

Permalink
Merge branch 'dev' into msal2-beta0-release
Browse files Browse the repository at this point in the history
  • Loading branch information
pkanher617 committed Mar 31, 2020
2 parents 2151f8e + 857ff1f commit 5b57594
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 69 deletions.
64 changes: 10 additions & 54 deletions lib/msal-core/src/ServerRequestParameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class ServerRequestParameters {
* @param request
* @param serverAuthenticationRequest
*/
populateQueryParams(account: Account, request: AuthenticationParameters, adalIdTokenObject?: any): void {
populateQueryParams(account: Account, request: AuthenticationParameters, adalIdTokenObject?: object, silentCall?: boolean): void {
let queryParameters: StringDict = {};

if (request) {
Expand All @@ -107,7 +107,7 @@ export class ServerRequestParameters {
}

/*
* adds sid/login_hint if not populated; populates domain_req, login_req and domain_hint
* adds sid/login_hint if not populated
* this.logger.verbose("Calling addHint parameters");
*/
queryParameters = this.addHintParameters(account, queryParameters);
Expand All @@ -117,7 +117,7 @@ export class ServerRequestParameters {

// Populate the extraQueryParameters to be sent to the server
this.queryParameters = ServerRequestParameters.generateQueryParametersString(queryParameters);
this.extraQueryParameters = ServerRequestParameters.generateQueryParametersString(eQParams);
this.extraQueryParameters = ServerRequestParameters.generateQueryParametersString(eQParams, silentCall);
}

// #region QueryParam helpers
Expand Down Expand Up @@ -167,27 +167,17 @@ export class ServerRequestParameters {
ssoType = SSOTypes.ID_TOKEN;
ssoData = idTokenObject.upn;
}
else {
ssoType = SSOTypes.ORGANIZATIONS;
ssoData = null;
}
}

serverReqParam = this.addSSOParameter(ssoType, ssoData);

// add the HomeAccountIdentifier info/ domain_hint
if (request && request.account && request.account.homeAccountIdentifier) {
serverReqParam = this.addSSOParameter(SSOTypes.HOMEACCOUNT_ID, request.account.homeAccountIdentifier, serverReqParam);
}

return serverReqParam;
}

/**
* @hidden
*
* Adds login_hint to authorization URL which is used to pre-fill the username field of sign in page for the user if known ahead of time
* domain_hint can be one of users/organizations which when added skips the email based discovery process of the user
* domain_hint if added skips the email based discovery process of the user - only supported for interactive calls in implicit_flow
* domain_req utid received as part of the clientInfo
* login_req uid received as part of clientInfo
* Also does a sanity check for extraQueryParameters passed by the user to ensure no repeat queryParameters
Expand Down Expand Up @@ -215,11 +205,6 @@ export class ServerRequestParameters {
qParams = this.addSSOParameter(SSOTypes.LOGIN_HINT, account.userName, qParams);
}
}

const populateReqParams = !qParams[SSOTypes.DOMAIN_REQ] && !qParams[SSOTypes.LOGIN_REQ];
if (populateReqParams) {
qParams = this.addSSOParameter(SSOTypes.HOMEACCOUNT_ID, account.homeAccountIdentifier, qParams);
}
}

return qParams;
Expand All @@ -245,46 +230,12 @@ export class ServerRequestParameters {
}
case SSOTypes.ID_TOKEN: {
ssoParam[SSOTypes.LOGIN_HINT] = ssoData;
ssoParam[SSOTypes.DOMAIN_HINT] = SSOTypes.ORGANIZATIONS;
break;
}
case SSOTypes.LOGIN_HINT: {
ssoParam[SSOTypes.LOGIN_HINT] = ssoData;
break;
}
case SSOTypes.ORGANIZATIONS: {
ssoParam[SSOTypes.DOMAIN_HINT] = SSOTypes.ORGANIZATIONS;
break;
}
case SSOTypes.CONSUMERS: {
ssoParam[SSOTypes.DOMAIN_HINT] = SSOTypes.CONSUMERS;
break;
}
case SSOTypes.HOMEACCOUNT_ID: {
const homeAccountId = ssoData.split(".");
const uid = CryptoUtils.base64Decode(homeAccountId[0]);
const utid = CryptoUtils.base64Decode(homeAccountId[1]);

// TODO: domain_req and login_req are not needed according to eSTS team
ssoParam[SSOTypes.LOGIN_REQ] = uid;
ssoParam[SSOTypes.DOMAIN_REQ] = utid;

if (utid === Constants.consumersUtid) {
ssoParam[SSOTypes.DOMAIN_HINT] = SSOTypes.CONSUMERS;
}
else {
ssoParam[SSOTypes.DOMAIN_HINT] = SSOTypes.ORGANIZATIONS;
}
break;
}
case SSOTypes.LOGIN_REQ: {
ssoParam[SSOTypes.LOGIN_REQ] = ssoData;
break;
}
case SSOTypes.DOMAIN_REQ: {
ssoParam[SSOTypes.DOMAIN_REQ] = ssoData;
break;
}
}

return ssoParam;
Expand All @@ -294,11 +245,16 @@ export class ServerRequestParameters {
* Utility to generate a QueryParameterString from a Key-Value mapping of extraQueryParameters passed
* @param extraQueryParameters
*/
static generateQueryParametersString(queryParameters: StringDict): string {
static generateQueryParametersString(queryParameters: StringDict, silentCall?: boolean): string {
let paramsString: string = null;

if (queryParameters) {
Object.keys(queryParameters).forEach((key: string) => {
// sid cannot be passed along with login_hint or domain_hint
if(key === Constants.domain_hint && (silentCall || queryParameters[SSOTypes.SID])) {
return;
}

if (paramsString == null) {
paramsString = `${key}=${encodeURIComponent(queryParameters[key])}`;
}
Expand Down
8 changes: 4 additions & 4 deletions lib/msal-core/src/UserAgentApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ export class UserAgentApplication {

this.updateCacheEntries(serverAuthenticationRequest, account, loginStartPage);

// populate QueryParameters (sid/login_hint/domain_hint) and any other extraQueryParameters set by the developer
// populate QueryParameters (sid/login_hint) and any other extraQueryParameters set by the developer
serverAuthenticationRequest.populateQueryParams(account, request);

// Construct urlNavigate
Expand Down Expand Up @@ -628,16 +628,16 @@ export class UserAgentApplication {
request.correlationId,
);

// populate QueryParameters (sid/login_hint/domain_hint) and any other extraQueryParameters set by the developer
// populate QueryParameters (sid/login_hint) and any other extraQueryParameters set by the developer
if (ServerRequestParameters.isSSOParam(request) || account) {
serverAuthenticationRequest.populateQueryParams(account, request);
serverAuthenticationRequest.populateQueryParams(account, request, null, true);
}
// if user didn't pass login_hint/sid and adal's idtoken is present, extract the login_hint from the adalIdToken
else if (!account && !StringUtils.isEmpty(adalIdToken)) {
// if adalIdToken exists, extract the SSO info from the same
const adalIdTokenObject = TokenUtils.extractIdToken(adalIdToken);
this.logger.verbose("ADAL's idToken exists. Extracting login information from ADAL's idToken ");
serverAuthenticationRequest.populateQueryParams(account, null, adalIdTokenObject);
serverAuthenticationRequest.populateQueryParams(account, null, adalIdTokenObject, true);
}
const userContainedClaims = request.claimsRequest || serverAuthenticationRequest.claimsValue;

Expand Down
9 changes: 2 additions & 7 deletions lib/msal-core/src/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export class Constants {
static get scopes(): string { return "scopes"; }

static get no_account(): string { return "NO_ACCOUNT"; }
static get consumersUtid(): string { return "9188040d-6c67-4c5b-b112-36a304b66dad"; }
static get upn(): string { return "upn"; }
static get domain_hint(): string { return "domain_hint"; }

static get prompt_select_account(): string { return "&prompt=select_account"; }
static get prompt_none(): string { return "&prompt=none"; }
Expand Down Expand Up @@ -117,13 +117,8 @@ export enum SSOTypes {
SID = "sid",
LOGIN_HINT = "login_hint",
ID_TOKEN ="id_token",
DOMAIN_HINT = "domain_hint",
ORGANIZATIONS = "organizations",
CONSUMERS = "consumers",
ACCOUNT_ID = "accountIdentifier",
HOMEACCOUNT_ID = "homeAccountIdentifier",
LOGIN_REQ = "login_req",
DOMAIN_REQ = "domain_req"
HOMEACCOUNT_ID = "homeAccountIdentifier"
};

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/msal-core/src/utils/UrlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export class UrlUtils {
url = url.toLowerCase();
const urlObject = this.GetUrlComponents(url);
const pathArray = urlObject.PathSegments;
if (tenantId && (pathArray.length !== 0 && (pathArray[0] === Constants.common || pathArray[0] === SSOTypes.ORGANIZATIONS))) {
if (tenantId && (pathArray.length !== 0 && pathArray[0] === Constants.common)) {
pathArray[0] = tenantId;
}
return this.constructAuthorityUriFromObject(urlObject, pathArray);
Expand Down
18 changes: 18 additions & 0 deletions lib/msal-core/test/ServerRequestParameters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,22 @@ describe("ServerRequestParameters.ts Class", function () {
expect(err.errorMessage).to.include(ClientConfigurationErrorMessage.invalidCorrelationIdError.desc);
});
});

describe("Query Parameters", function () {

it("test hints populated using queryParameters", function () {
const eQParams = {domain_hint: "MyDomain.com", locale: "en-us"};
const extraQueryParameters = ServerRequestParameters.generateQueryParametersString(eQParams);
expect(extraQueryParameters).to.include("domain_hint");
expect(extraQueryParameters).to.include("locale");
});

it("test hints populated using queryParameters", function () {
const eQParams = { domain_hint: "MyDomain.com", locale: "en-us" };
const extraQueryParameters = ServerRequestParameters.generateQueryParametersString(eQParams, true);
expect(extraQueryParameters).to.not.include("domain_hint");
expect(extraQueryParameters).to.include("locale");
});

});
});
4 changes: 1 addition & 3 deletions lib/msal-core/test/UserAgentApplication.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,7 @@ describe("UserAgentApplication.ts Class", function () {
expect(url).to.include("&state");
expect(url).to.include("&client_info=1");
expect(url).to.include("&login_hint=" + "some_id");
expect(url).to.include("&login_req=1234");
expect(url).to.include("&domain_req=5678");
expect(url).to.include("&domain_hint");
expect(url).to.not.include("&domain_hint");
expect(url).to.include(Constants.prompt_select_account);
expect(url).to.not.include(Constants.prompt_none);
done();
Expand Down

0 comments on commit 5b57594

Please sign in to comment.