[microsoft-authentication] Extend authentication session to return id tokens (#114675)
This commit is contained in:
parent
5a3fedf0c4
commit
582ea371c2
2 changed files with 37 additions and 6 deletions
|
@ -16,6 +16,7 @@ import { toBase64UrlEncoding } from './utils';
|
||||||
import fetch, { Response } from 'node-fetch';
|
import fetch, { Response } from 'node-fetch';
|
||||||
import { sha256 } from './env/node/sha256';
|
import { sha256 } from './env/node/sha256';
|
||||||
import * as nls from 'vscode-nls';
|
import * as nls from 'vscode-nls';
|
||||||
|
import { MicrosoftAuthenticationSession } from './microsoft-authentication';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ const tenant = 'organizations';
|
||||||
|
|
||||||
interface IToken {
|
interface IToken {
|
||||||
accessToken?: string; // When unable to refresh due to network problems, the access token becomes undefined
|
accessToken?: string; // When unable to refresh due to network problems, the access token becomes undefined
|
||||||
|
idToken?: string; // depending on the scopes can be either supplied or empty
|
||||||
|
|
||||||
expiresIn?: number; // How long access token is valid, in seconds
|
expiresIn?: number; // How long access token is valid, in seconds
|
||||||
expiresAt?: number; // UNIX epoch time at which token will expire
|
expiresAt?: number; // UNIX epoch time at which token will expire
|
||||||
|
@ -71,6 +73,11 @@ export interface ITokenResponse {
|
||||||
id_token?: string;
|
id_token?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IMicrosoftTokens {
|
||||||
|
accessToken: string;
|
||||||
|
idToken?: string;
|
||||||
|
}
|
||||||
|
|
||||||
function parseQuery(uri: vscode.Uri) {
|
function parseQuery(uri: vscode.Uri) {
|
||||||
return uri.query.split('&').reduce((prev: any, current) => {
|
return uri.query.split('&').reduce((prev: any, current) => {
|
||||||
const queryString = current.split('=');
|
const queryString = current.split('=');
|
||||||
|
@ -228,29 +235,36 @@ export class AzureActiveDirectoryService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async convertToSession(token: IToken): Promise<vscode.AuthenticationSession> {
|
private async convertToSession(token: IToken): Promise<MicrosoftAuthenticationSession> {
|
||||||
const resolvedToken = await this.resolveAccessToken(token);
|
const resolvedTokens = await this.resolveAccessAndIdTokens(token);
|
||||||
return {
|
return {
|
||||||
id: token.sessionId,
|
id: token.sessionId,
|
||||||
accessToken: resolvedToken,
|
accessToken: resolvedTokens.accessToken,
|
||||||
|
idToken: resolvedTokens.idToken,
|
||||||
account: token.account,
|
account: token.account,
|
||||||
scopes: token.scope.split(' ')
|
scopes: token.scope.split(' ')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private async resolveAccessToken(token: IToken): Promise<string> {
|
private async resolveAccessAndIdTokens(token: IToken): Promise<IMicrosoftTokens> {
|
||||||
if (token.accessToken && (!token.expiresAt || token.expiresAt > Date.now())) {
|
if (token.accessToken && (!token.expiresAt || token.expiresAt > Date.now())) {
|
||||||
token.expiresAt
|
token.expiresAt
|
||||||
? Logger.info(`Token available from cache, expires in ${token.expiresAt - Date.now()} milliseconds`)
|
? Logger.info(`Token available from cache, expires in ${token.expiresAt - Date.now()} milliseconds`)
|
||||||
: Logger.info('Token available from cache');
|
: Logger.info('Token available from cache');
|
||||||
return Promise.resolve(token.accessToken);
|
return Promise.resolve({
|
||||||
|
accessToken: token.accessToken,
|
||||||
|
idToken: token.idToken
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Logger.info('Token expired or unavailable, trying refresh');
|
Logger.info('Token expired or unavailable, trying refresh');
|
||||||
const refreshedToken = await this.refreshToken(token.refreshToken, token.scope, token.sessionId);
|
const refreshedToken = await this.refreshToken(token.refreshToken, token.scope, token.sessionId);
|
||||||
if (refreshedToken.accessToken) {
|
if (refreshedToken.accessToken) {
|
||||||
return refreshedToken.accessToken;
|
return {
|
||||||
|
accessToken: refreshedToken.accessToken,
|
||||||
|
idToken: refreshedToken.idToken
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
|
@ -501,6 +515,7 @@ export class AzureActiveDirectoryService {
|
||||||
expiresIn: json.expires_in,
|
expiresIn: json.expires_in,
|
||||||
expiresAt: json.expires_in ? Date.now() + json.expires_in * 1000 : undefined,
|
expiresAt: json.expires_in ? Date.now() + json.expires_in * 1000 : undefined,
|
||||||
accessToken: json.access_token,
|
accessToken: json.access_token,
|
||||||
|
idToken: json.id_token,
|
||||||
refreshToken: json.refresh_token,
|
refreshToken: json.refresh_token,
|
||||||
scope,
|
scope,
|
||||||
sessionId: existingId || `${claims.tid}/${(claims.oid || (claims.altsecid || '' + claims.ipd || ''))}/${uuid()}`,
|
sessionId: existingId || `${claims.tid}/${(claims.oid || (claims.altsecid || '' + claims.ipd || ''))}/${uuid()}`,
|
||||||
|
|
16
extensions/microsoft-authentication/src/microsoft-authentication.d.ts
vendored
Normal file
16
extensions/microsoft-authentication/src/microsoft-authentication.d.ts
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { AuthenticationSession } from 'vscode';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a session of a currently logged in Microsoft user.
|
||||||
|
*/
|
||||||
|
export interface MicrosoftAuthenticationSession extends AuthenticationSession {
|
||||||
|
/**
|
||||||
|
* The id token.
|
||||||
|
*/
|
||||||
|
idToken?: string;
|
||||||
|
}
|
Loading…
Reference in a new issue