Nant, Vault & Windows Integrated Authentication

2019-07-20 07:42发布

问题:

I am wanting to perform a number of tasks in SourceGear Vault (V4.1.4) with Nant (V0.86.3317.0).

Is there any way we can get Vault to use Windows Authentication from Nant to create the connection?

The Nant block I am using to initialise the vault connect is :

<target name="InitialiseVaultSettings">
<echo>InitialiseVaultSettings</echo>
<vaultsetloginoptions user="${vault.Username}" password="${vault.Password}" URL="${vault.Host}" repository="${vault.Repository}" />
<vaultsetworkingfolder repositoryFolderPath="${vault.Folder}" diskPath="${vault.WorkingDirectory}" createDiskPath="true" />

As I am working on the project with other developers, hard coding user names and passwords into the Nant build file is not a good idea. Both username and password are required options in the vaultsetloginoptions command.

Other alternatives (all with catches) include :

(a) Hardcode the 'Admin' account into the Nant properties and log vault in using that. This isn't so great, as we then loose an audit trail of who is responsible for the check-in / check-out operations the nant script performs. It also causes problems when the solution has files checked out (part of the script ensures all files are checked back into source control prior to generating a label in Vault).

(b) Use a C# script from the Nant code to set the properties of username and password dynamically ... except we've then got a problem of getting the password from the user still

(c) Read the stored profile information from the Vault client and connect using that (except I'm not sure where it is stored).

Thanks for your consideration.

回答1:

I'm unfamiliar with Vault so please forgive the potential vagueness of this answer. I've worked with NAnt a lot and anything that gets executed (tasks, execs, etc) have the inherent potential to be running in integrated authenticated mode.

In the end, authentication gets passed along to whichever user happens to be running the parent NAnt process. That being said, this could be a sign that Vault's NAnt tasks don't support integrated authentication? Meaning, if the vaultsetloginoptions task requires the user and password arguments, then there is no good way to pass along credentials (as you pointed out).

If there happens to be no workarounds for the potential lacking in Vault's NAnt tasks it might be possible to use the <exec> task to call a command line version of their client side tool (not even sure if they have one). If this is an option, integrated authentication will automatically kick in as long as the user running the NAnt process is the same as the one needing to connect to Vault.

We've had to do this for a few things we integrate with in our build process. We've either exec'd out to the command line version or have written our own Task(s) by extending the NAnt framework. Either way, this should be possible.

Update

Did some looking around on the Vault forums and it seems that the AD integration is merely a way to have Vault Client prompt the user and pass along to server. From the forum:

The Vault client will always prompt for the username/password. Our AD integration is limited to the server verifying that the password entered matches the password in Active Directory.

Therefore, there is no true way for the client to pass along windows authentication information in a built-in way. The Vault client program requires one to input the username and password when running in AD mode. Sadly, it would seem without storing the username/password, the chances of seamless NAnt integration is a far shot.



回答2:

I have implemented with success the prototype to work-around this problem.

Full Source and Binaries for the workaround described below can be found here :

Vault Login Extensions

I have created some custom NAnt tasks and functions.

<VaultLogin> checks the Windows Registry for username and password information previously stored. If not found it prompts the user with a Login window. It stores the entries in two functions and clears the registry (in case the login fails - see <SaveVaultLogin> below) :

${VaultLoginFunctions::UserName()}
${VaultLoginFunctions::Password()}

The <vaultsetloginoptions> task is then able to use the functions :

<vaultsetloginoptions user="${VaultLoginFunctions::UserName()}" password="${VaultLoginFunctions::Password()}" URL="${vault.Host}" repository="${vault.Repository}" />

After calling the <vaultsetloginoptions> task, we then call the <SaveVaultLogin> task which writes the username and password values back to the registry. This ensures that only successful authentication details are stored (as the script fails at the task if the username and password are incorrect.

This is the code block put together :

  <target name="InitialiseVaultSettings">
<echo>InitialiseVaultSettings</echo>

<loadtasks assembly="CompassHealth.NAntExtensions.Tasks.dll" />

<VaultLoginGet />
<echo message="UserName = ${VaultLoginFunctions::UserName()}" />

<vaultsetloginoptions user="${VaultLoginFunctions::UserName()}" password="${VaultLoginFunctions::Password()}" URL="${vault.Host}" repository="${vault.Repository}" />

<vaultsetworkingfolder repositoryFolderPath="${vault.Folder}" diskPath="${vault.WorkingDirectory}" createDiskPath="true" />


<!-- need to save the login here, as it is cleared once VaultLoginGet is called, this ensures that only correct username and password are stored -->
<VaultLoginSave />    

Update : link to binaries and source for work-around now at top of post.



回答3:

After looking at Scott Saad's suggestion, unfortunately there appears to be no option in the command line tool either to call it using Windows Authentication.

My current thinking is in line with (b) above.

I'll create a library that can be called from the Nant script, asking for the current windows user's Vault username and password.

The library will look in a resigstry entry for a previously entered Vault username and login for this windows user. If it exists, it will be passed to the script without any user interaction.

If this username / password fails the vault login, or if it doesn't exist then the library will provide a dialog for the user to enter the current vault username and password.

The user's entry will be stored in the registry (encrypted) meaning this should only have to be entered once each time the Vault username and password change.

Not an ideal solution, but should be relatively straight-forward and an acceptable enough work around.

What do you think?