

Rider NuGet Credential Provider for JetBrains Space private repositories
source link: https://blog.jetbrains.com/dotnet/2021/05/20/rider-nuget-credential-provider-for-jetbrains-space-private-repositories/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Rider NuGet Credential Provider for JetBrains Space private repositories
With the 2021.1 release of our IDE’s, we also made available the Space plugin. This plugin lets you authenticate with a Space organization, work with automation scripts for CI/CD, and browse Space code reviews.
In Space, you can also create private NuGet feeds that your team can use. So, the .NET developer advocacy team was thinking…
What if we create a Rider plugin, that automatically logs you in to your private Space NuGet repositories?
Welcome, Rider NuGet Credential Provider for Space!
Intermezzo: What is Space?
Not everyone may have already heard about Space, so let’s try to summarize what it is in one sentence…
JetBrains Space brings software developers together with chats, project management, issue tracking, Git hosting, CI/CD, and package repositories.
Create a free Space organization
There is much more functionality built in, such as chats, a team directory, and more. Go check it out if you’re curious about what Space has to offer.
End intermezzo.
Let’s look at what our plugin does, and then look at how it was developed.
Working with NuGet packages from Space in Rider
When you have the Space plugin installed and configured in your IDE, the Rider NuGet Credential Provider for Space automatically authenticates with private NuGet feeds hosted in Space packages.
First, authenticate with Space from within your IDE. Check the Space plugin documentation for more information.
Next, configure a Space NuGet feed in your NuGet.config
file. You can add a NuGet.config
next to your solution file,
and configure it similar to the following:
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="SpaceNuGet" value="https://nuget.pkg.jetbrains.space/mycompany/p/projectkey/mynuget/v3/index.json" protocolVersion="3" /> </packageSources> </configuration>
A picture says more than a thousand words, so here’s what our plugin does:

Note: Make sure you have Rider credential providers enabled. In Settings | Build, Execution, Deployment | NuGet, select Rider integrated or NuGet/.NET CLI plugins, then Rider integrated.
Background about how this plugin works
In Rider 2018.2, we introduced credential providers for private feeds in our NuGet client. While it has evolved, and now also supports dotnet
and NuGet.exe
credential providers, the extension point for NuGet credential providers is still there. Great!
Building a plugin for Rider
Using the Rider plugin template, we got to work and created a barebones plugin that we could run in Rider.
We stripped off the ReSharper bits, as the NuGet credential provider extension point is Rider-only.
Adding plugin dependencies and registering an extension
Next, we updated the build.gradle
file, and made some changes to the intellij
section. Our plugin would need access to the Space plugin, so we need a dependency on it:
// ... intellij { type = 'RD' version = '2021.1.0' downloadSources = false instrumentCode = false plugins("com.jetbrains.space:211.6693.108") } // ...
Using this approach, we can make use of the classes and services provided by the Space plugin to get information about the currently logged in user.
Note: Rider is built on the IntelliJ platform and ReSharper, as described in more detail in this article in CODE Magazine. Our plugin lives on the IntelliJ side, which means we need to write it in a JVM language like Kotlin, and make use of build tools like Gradle.
In the plugin.xml
manifest, which describes our plugin and what it provides, we added a plugin dependency. Doing so ensures that if you download our plugin in Rider, the IDE will also download the Space plugin. A <depends>com.jetbrains.space</depends>
did the trick.
The credential providers post describes how to add a custom credential provider, which is what we did:
<extensions defaultExtensionNs="com.intellij"> <nugetCredentialProvider implementation="org.jetbrains.rider.nuget.credentials.providers.space.SpaceNuGetCredentialProvider" order="first" /> </extensions>
One thing left: building the actual credential provider!
Implementing NuGetCredentialProvider
Our custom NuGetCredentialProvider
, aptly named SpaceNuGetCredentialProvider
, is used by Rider when credentials are required to access a NuGet feed.
It has to:
- Let Rider know if it can handle a specific NuGet URL (in the
appliesTo(project: Project, uri: URI): Boolean
function); and - Provide access details if possible (in the
getProviderResponse(project: Project, uri: URI, isRetry: Boolean): NuGetCredentialProviderResponse
function).
A skeleton NuGet credential provider in Rider looks like this:
class SpaceNuGetCredentialProvider : NuGetCredentialProvider { override fun appliesTo(project: Project, uri: URI): Boolean { } override fun getProviderResponse(project: Project, uri: URI, isRetry: Boolean): NuGetCredentialProviderResponse { } }
In the appliesTo
function, we implemented a check to see if the IDE is logged in, and whether the URL of the feed matches the Space organization we’re logged in to:
override fun appliesTo(project: Project, uri: URI): Boolean { if (!settings.serverSettings.enabled) return false // uri and server are Space cloud, and are the same organization if (uri.host.equals("nuget.pkg.jetbrains.space", ignoreCase = true)) { val organizationName = uri.path.trimStart('/').split('/').firstOrNull() ?: return false if (settings.serverSettings.server.startsWith("https://$organizationName.jetbrains.space", ignoreCase = true)) { return true } } return false }
Not 100% bullet proof, but it will do for this first version of our plugin.
Next, the getProviderResponse
function. It has to return a NuGetCredentialProviderResponse
, which will tell Rider what the authentication status is. First, we check whether we’re still logged in. If not, we can return NuGetCredentialProviderResponse.PROVIDER_NOT_APPLICABLE
.
The second step is to check whether the user has manually configured credentials (in the Sources tab of the NuGet tool window). Credential providers don’t have to do this, but it’s nice if they give the user a means of overriding credentials.
override fun getProviderResponse(project: Project, uri: URI, isRetry: Boolean): NuGetCredentialProviderResponse { if (!settings.serverSettings.enabled) return NuGetCredentialProviderResponse.PROVIDER_NOT_APPLICABLE // Use already stored credentials, if available. // The user may have configured these manually in Rider UI, and we want to try those first. if (!isRetry) { val storedCredentials = RiderNuGetCredentialsRepo.loadCredentialsForFeed(uri.toString()) if (storedCredentials != null) { return NuGetCredentialProviderResponse( NuGetCredentials(storedCredentials.user, storedCredentials.password), NuGetCredentialProviderStatus.Success, null) } } // ... }
Only after these two checks, we call into the Space plugin and retrieve an authentication token for the current user.
// ... val workspaceContext = SpaceNuGetWorkspace.getWorkspaceContext() ?: return NuGetCredentialProviderResponse.PROVIDER_NOT_APPLICABLE val username = workspaceContext.profile.username val accessToken = workspaceContext.circletClient.tokenSource.token().accessToken return NuGetCredentialProviderResponse( NuGetCredentials(username, RdSecureString(accessToken)), NuGetCredentialProviderStatus.Success, null)
That’s it! Now, you may wonder… Where is the source code for this plugin? Currently, it resides in a private (Space) repository, but we plan on publishing it in the future.
Conclusion
In this blog post, we wanted to provide some resources related to building Rider plugins. We walked through how we built our own plugin for Rider, to help with private NuGet feeds hosted in Space.
Give JetBrains Space a try, and make sure to use our Rider NuGet Credential Provider for Space if you do.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK