-
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
Authentication Provider API #88309
Comments
Based on feedback from the API call, I've some changes to the API: export interface Session {
id: string;
accessToken: string;
displayName: string;
}
export interface AuthenticationProvider {
readonly id: string;
readonly displayName: string;
readonly onDidChangeSessions: Event<void>;
/**
* Returns an array of current sessions.
*/
getSessions(): Promise<ReadonlyArray<Session>>;
/**
* Prompts a user to login.
*/
login(): Promise<Session>;
logout(sessionId: string): Promise<void>;
}
export namespace authentication {
export function registerAuthenticationProvider(provider: AuthenticationProvider): Disposable;
/**
* Fires with the provider id that was registered or unregistered.
*/
export const onDidRegisterAuthenticationProvider: Event<string>;
export const onDidUnregisterAuthenticationProvider: Event<string>;
/**
* Fires with the provider id that changed sessions.
*/
export const onDidChangeSessions: Event<string>;
export function login(providerId: string): Promise<Session>;
export function logout(providerId: string, accountId: string): Promise<void>;
export function getSessions(providerId: string): Promise<ReadonlyArray<Session> | undefined>;
}
We had discussed combining We also discussed moving the authentication provider display name out to a contribution point - I think this is reasonable, I just haven't done this yet. One open question is about additional information that might be needed for login and on the session itself. For OAuth, the |
Sounds very interesting. I have use case this would come handy. Right now it's just custom development tools implementation, a bit hacky though. Process is to get access token written down to a temporary file in the project's directory for running integration tests against system requiring OAuth login through browser (and MFA) and there's no way adding more permanent application authentication. It's done by running a console script activating OAuth process, then giving url for user to visit in browser and copy the url back to the script waiting for input in console. Then the access token is written to a json file which can be then consumed by other scripts. Was considering even to have headless chrome to avoid the browser step. Now if the VSCode first class standard OAuth provider (would cover many login cases) could be configured per project basis (.vscode/extensions.json, .vscode/authentication.json?) to write the returned/refreshed access token to a specified file in active project, and have easy way to select specific OAuth target account to login manually... |
The Docker extension would get a lot of mileage out of some standardization of OAuth flows: microsoft/vscode-docker#869. For instance, if VSCode could take care of password retrieval and storage, and facilitate browser-based logins (like what the Azure Account extension has to do), that would help a lot. |
This is missing the authentication label. |
So would all extensions loading into VSCode be able to read all |
@OkGoDoIt There is a feature called "Manage Trusted Extensions" that should address that. There's a brief description in #93811. Regarding the API, check vscode/src/vs/vscode.proposed.d.ts Lines 111 to 119 in 9be0faf
which indicates that a user must consent to sharing authentication information with an extension in order for it to be able to retrieve the session. |
When the GitHub Pull Request & Issues extension switched to using this new Authentication API it lost the support for enterprise GitHub deployments. I assume that's because the above API is missing something fundamental for that specific style of access (API key based instead of username/password based?) What are the plans for updating the API to add in what was missing for GitHub enterprise auth? I assume other extensions will need similar capabilities as well. |
Issue in question: This has broken GithubPullRequests for everyone using enterprise |
Not completely, we have a very small list of extensions that are opted into being able to use the proposed API. This helps us iterate on and test API, but is also a source of occasional pain as we've sometimes unintentionally broken these extensions. |
Yes, it was proposed, and (iirc, also implemented) in the experimental version. But as I said, it did not make it into the final version of the API, for some reason. No I'm bringing up this issue, particularly because it is hard to test authentication without an ability to logout. |
Sorry for possibly stupid question. But with this proposal can there be "SshAuthenticationProvider" which will store my ssh username + password (say in windows credential manager) and provide it to vscode-remote-ssh plugin? |
@RMacfarlane When trying to get token for Microsoft I get following error -
What do I need to do? Is there any way to change the applicationid? |
I am facing the same issue as @ankitbko |
Will it be possible to contribute several auth provider for the same id? For instance my extension has an access to a generic oauth provider which can handle GitHub as well already instead of using the github authentication extension. |
What scopes/API are you using here? |
I am using |
@TylerLeonhardt I am also hitting the same issue when trying to hit ADO apis with specific scopes. Is this solution recommended for auth against ADO? +1 to the question about logout, is there any other way to log out since its still in proposed-api? |
@Domiii in case you were still stuck on this, looks like the accounts (person icon) on the activity bar has a way to log out. It will show you a list of accounts used to log in and what extensions are using it. |
No, each auth provider needs a unique id. I'm finalizing the /**
* Options for creating an [AuthenticationProvider](#AuthentcationProvider).
*/
export interface AuthenticationProviderOptions {
/**
* Whether it is possible to be signed into multiple accounts at once with this provider.
* If not specified, will default to false.
*/
readonly supportsMultipleAccounts?: boolean;
}
/**
* An [event](#Event) which fires when an [AuthenticationSession](#AuthenticationSession) is added, removed, or changed.
*/
export interface AuthenticationProviderAuthenticationSessionsChangeEvent {
/**
* The [AuthenticationSession](#AuthenticationSession)s of the [AuthenticationProvider](#AuthentiationProvider) that have been added.
*/
readonly added: ReadonlyArray<AuthenticationSession>;
/**
* The [AuthenticationSession](#AuthenticationSession)s of the [AuthenticationProvider](#AuthentiationProvider) that have been removed.
*/
readonly removed: ReadonlyArray<AuthenticationSession>;
/**
* The [AuthenticationSession](#AuthenticationSession)s of the [AuthenticationProvider](#AuthentiationProvider) that have been changed.
*/
readonly changed: ReadonlyArray<AuthenticationSession>;
}
/**
* A provider for performing authentication to a service.
*/
export interface AuthenticationProvider {
/**
* An [event](#Event) which fires when the array of sessions has changed, or data
* within a session has changed.
*/
readonly onDidChangeSessions: Event<AuthenticationProviderAuthenticationSessionsChangeEvent>;
/**
* 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.
* @returns A promise that resolves to an array of authentication sessions.
*/
// eslint-disable-next-line vscode-dts-provider-naming
getSessions(scopes?: string[]): Thenable<ReadonlyArray<AuthenticationSession>>;
/**
* Prompts a user to login.
* @param scopes A list of scopes, permissions, that the new session should be created with.
* @returns A promise that resolves to an authentication session.
*/
// eslint-disable-next-line vscode-dts-provider-naming
createSession(scopes: string[]): Thenable<AuthenticationSession>;
/**
* Removes the session corresponding to session id.
* @param sessionId The id of the session to remove.
*/
// eslint-disable-next-line vscode-dts-provider-naming
removeSession(sessionId: string): Thenable<void>;
}
/**
* Namespace for authentication.
*/
export namespace authentication {
...
/**
* Register an authentication provider.
*
* There can only be one provider per id and an error is being thrown when an id
* has already been used by another provider. Ids are case-sensitive.
*
* @param id The unique identifier of the provider.
* @param label The human-readable name of the provider.
* @param provider The authentication provider provider.
* @params options Additional options for the provider.
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
*/
export function registerAuthenticationProvider(id: string, label: string, provider: AuthenticationProvider, options?: AuthenticationProviderOptions): Disposable;
} |
So what scopes does this supports for now? Will AZDO and Graph APIs be supported by Microsoft provider? |
This issue is just tracking the API, the implementation of the Microsoft provider is unchanged. Right now the provider supports getting an ARM token with |
Does this API allow to create an extension that is able to fetch access tokens from AAD B2C with user delegation? |
@monil-patel thank you for the info! I have not revisited the issue yet, but will very soon; so, your help is much appreciated :) |
Problem
There are currently some extensions that attempt to provide authentication abilities that can be reused by other extensions. (An example being the Azure Account extension). Now that we've begun working on login for settings sync, it's worth revisiting if authentication should be a first-class concept in VS Code. By exposing an API to contribute an authentication flow
Proposal
I propose introducing a concept of an "AuthenticationProvider". Such a provider implements methods for logging in and logging out of a specified account, and exposes a list of accounts that are currently available with an event listener for changes to these. This abstracts away refreshing tokens from consumers - the AuthenticationProvider extension can manage refreshing in the background and fire an event when the accessToken has been changed.
Consumers would need to know the id of the provider they're looking for. For example, the settings sync code would look for an "MSA" provider since this is what the setting sync backend currently needs.
Since the authentication provider extension would be activated in each VS Code window, the extension would be responsible for synchronizing state across instances. By default, such extensions would have ["ui", "workspace"] extensionKind, so that they can store and read credentials on the local machine in both the desktop and web case.
The text was updated successfully, but these errors were encountered: