-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
API support for multiple AuthenticationSessions with the same scopes. #152399
Comments
* Initial getSessions API ref #152399 * include provider id in key
I'm merging #177263 into this... In the end, here's what we'll do:
export interface AuthenticationForceNewSessionOptions {
detail: string;
}
/**
* Options used in {@link authentication.getSession} to be used when forcing the recreation of an {@link AuthenticationSession}.
*/
export interface AuthenticationForceNewSessionOptions {
readonly session?: AuthenticationSession;
}
export namespace authentication {
/**
* Get all authentication sessions matching the desired scopes that this extension has access to. In order to request access,
* use {@link getSession}. To request an additional account, specify {@link AuthenticationGetSessionOptions.clearSessionPreference}
* and {@link AuthenticationGetSessionOptions.createIfNone} together.
*
* Currently, there are only two authentication providers that are contributed from built in extensions
* to the editor that implement GitHub and Microsoft authentication: their providerId's are 'github' and 'microsoft'.
*
* @param providerId The id of the provider to use
* @param scopes A list of scopes representing the permissions requested. These are dependent on the authentication provider
* @returns A thenable that resolves to a readonly array of authentication sessions.
*/
export function getSessions(providerId: string, scopes: readonly string[]): Thenable<readonly AuthenticationSession[]>;
} |
One thing left to be talked about is how the AuthProvider receives the session that needs to be recreated. There are a couple options:
createSession(scopes: readonly string[], options?: { session: AuthenticationSession }): Thenable<AuthenticationSession>; |
This will allow you to have workspace level preferences of accounts. The ideal flow is that an extension can ask for the preferred session (silently) first, to not annoy the user... and if the extension/user wants to use a different account, the extension can ask to clear the session preference and the user will select the account they want to use. Also serializes the adding of accounts in the menu which allows every account shows up instead of just the last account (a bug I noticed doing this work) ref #152399
This will allow you to have workspace level preferences of accounts. The ideal flow is that an extension can ask for the preferred session (silently) first, to not annoy the user... and if the extension/user wants to use a different account, the extension can ask to clear the session preference and the user will select the account they want to use. Also serializes the adding of accounts in the menu which allows every account shows up instead of just the last account (a bug I noticed doing this work) ref #152399
@bwateratmsft and @alexweininger can hopefully provide feedback on the overall plan, as I'm not as involved in VS Code extension development these days. Of the two recreate session options, I think it depends on whether we really mean "re-creation" or "replacement". If the former, where the session is essentially the same but just "refreshed", then a separate |
API Sync likes the 2nd bullet, and I agree that maybe |
Got some other ideas... this would help manipulate the session preference so that forcing a new session would "just work". export interface AuthenticationGetSessionOptions {
clearSessionPreference?: boolean | AuthenticationSession;
} or export interface AuthenticationGetSessionOptions {
clearSessionPreference?: boolean | { newSessionPreference: AuthenticationSession };
} There's also this, but I'm not the biggest fan. export interface AuthenticationGetSessionOptions {
silent?: boolean | AuthenticationSession;
} Also, it has come to my attention that even today, the AuthProvider is not informed as to which session is the preferred session... in other words, which one to re-create... so we still need: createSession(scopes: readonly string[], options?: { session: AuthenticationSession }): Thenable<AuthenticationSession>; |
Isn't calling |
Not fully. If no session is passed in to |
Revisiting this... I have a new proposal. I have not liked how Instead, it would be better to separate accounts and the scopes... so that means the following proposal: declare module 'vscode' {
// FOR THE CONSUMER
export namespace authentication {
/**
* Get all accounts that the user is logged in to for the specified provider.
* Use this paired with {@link getSession} in order to get an authentication session for a specific account.
*
* Currently, there are only two authentication providers that are contributed from built in extensions
* to the editor that implement GitHub and Microsoft authentication: their providerId's are 'github' and 'microsoft'.
*
* Note: Getting accounts does not imply that your extension has access to that account or its authentication sessions. You can verify access to the account by calling {@link getSession}.
*
* @param providerId The id of the provider to use
* @returns A thenable that resolves to a readonly array of authentication accounts.
*/
export function getAccounts(providerId: string): Thenable<readonly AuthenticationSessionAccountInformation[]>;
}
export interface AuthenticationGetSessionOptions {
/**
* The account that you would like to get a session for. This is passed down to the Authentication Provider to be used for creating the correct session.
*/
account?: AuthenticationSessionAccountInformation;
}
// FOR THE AUTH PROVIDER
export interface AuthenticationProviderSessionOptions {
/**
* The account that is being asked about. If this is passed in, the provider should
* attempt to return the sessions that are only related to this account.
*/
account?: AuthenticationSessionAccountInformation;
}
export interface AuthenticationProvider {
/**
* Get a list of sessions.
* @param scopes An optional list of scopes. If provided, the sessions returned should match
* these permissions, otherwise all sessions should be returned.
* @param options Additional options for getting sessions.
* @returns A promise that resolves to an array of authentication sessions.
*/
getSessions(scopes: readonly string[], options: AuthenticationProviderSessionOptions): Thenable<AuthenticationSession>;
/**
* Prompts a user to login.
*
* If login is successful, the onDidChangeSessions event should be fired.
*
* If login fails, a rejected promise should be returned.
*
* If the provider has specified that it does not support multiple accounts,
* then this should never be called if there is already an existing session matching these
* scopes.
* @param scopes A list of scopes, permissions, that the new session should be created with.
* @param options Additional options for creating a session.
* @returns A promise that resolves to an authentication session.
*/
createSession(scopes: readonly string[], options: AuthenticationProviderSessionOptions): Thenable<AuthenticationSession>;
}
} This actually follows a pretty established model that MSALjs uses where you get an account and then you pass that account in to get a token for that account. This also is a nicer fit for multiple GitHub Auth as well and I think that it would be easier to support multiple GitHub accounts that way. |
Moving to July for potential finalization |
Currently VS Code provides an API (
vscode.authentication.getSession()
) that allows extensions to get anAuthenticationSession
for a given set of scopes. Depending on the options passed it, if there are no existing sessions, VS Code may prompt the user to sign in. If there are more than one session with those scopes, VS Code may prompt the user to select which one to use. At the end of the day, however, the extension is returned at most oneAuthenticationSession
that corresponds to a single account.In some cases extensions may want to know about all the
AuthenticationSession
instances associated with a specific set of scopes, in order to provide multi-account experiences or to have its own UX for choosing which account is used in a specific setting (where VS Code's current selection UX might not be appropriate). For example, a tree view that shows assets associated with multiple accounts rather than requiring the user to constantly switch between accounts.What I propose is a new function,
getSessions()
with similar semantics as that same method on theAuthenticationProvider
. If matching sessions exist, all will be returned. If none exist, an empty array is returned. Calling the function will not result in any user prompts (to select between accounts or to sign in) aside, perhaps, from the initial "do you allow this extension to access these accounts" prompt.The text was updated successfully, but these errors were encountered: