Skip to content

Demo project that use UserSecrets in a Xamarin Forms App

License

Notifications You must be signed in to change notification settings

ncarandini/XFUserSecrets

Repository files navigation

XFUserSecrets

Demo project that use UserSecrets in a Xamarin Forms App

Description

This project demonstrate the use of UserSecrets to embed configuration data into a Xamarin Forms App without exposing them to the GitHub project.

Because the UserSecrets json data is embedded into the app, we can read it easily. Moreover, because the UserSecrets file is outside the git root folder, it's never pushed to the GitHub repository.

Create a "UserSecrets" file

Visual Studio has an easy way to create UserSecrets by right clicking on the Xamarin Forms common project and select Manage User Secrets :

image

Elas, Visual studio for Mac don't have any command to manage user secrets, but we can use the .NET Core CLI (Command-Line Interface):

  1. Open the Terminal;
  2. Change directory to the Xamarin Forms common project folder
  3. Execute dotnet user-secrets init

image

Using the .NET CLI, we can also add one or more secrets, like with dotnet user-secrets set "MySecret" "HGttG:42" :

image

More info on user secrets can be found in the Microsoft documentation.

The "secrets.json" file

The good thing of using user secrets is that a secrets.json file is created and stored outside of the solution folder in a place not managed by the git versioning system.

  • On Windows platform the path is %APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
  • On Unix and Mac OSX platforms the path is ~/.microsoft/usersecrets/<user_secrets_id>/secrets.json

The UserSecretsId is a Guid (Globally Unique Identifier) assigned during the user secrets initialization and stored on the .csproj file:

image

MSBuild customization

To add the secret.json file as an EmbeddedResource to the Xamarin Forms common project we need to execute some steps before the build process:

  1. Check that we are building a debug version;
  2. Verify that the project is using UserSecrets;
  3. Add the file to the EmbeddedResource file list.

In order to do that, we have multiple choices:

  • Modify the .csproj file
  • Create a .targets file and add an import command at the end of the .csproj file
  • Create a Directory.Build.targets file on the same folder of the .csproj file

The last one is preferable because we only needs to add a file that we can just copy and paste on every project where we want to use UserSecrets, without touching the .csproj file.

When MSBuild runs, Microsoft.Common.targets searches the directory structure for the Directory.Build.targets file. If it finds one, it imports the targets without the need to explicitly import them on the .csproj file. More info about the Directory.Build.propsand Directory.Build.targets files can be found on Microsoft Docs.

Here is the Directory.Build.targets file that I've composed to implement those steps (also thanks to Jonathan Dick help):

<Project>
  <Target Name="AddUserSecrets"
          BeforeTargets="PrepareForBuild"
          Condition=" '$(Configuration)' == 'Debug' And '$(UserSecretsId)' != '' ">
    <PropertyGroup>
      <UserSecretsFilePath Condition=" '$(OS)' == 'Windows_NT' ">
        $([System.Environment]::GetFolderPath(SpecialFolder.UserProfile))\AppData\Roaming\Microsoft\UserSecrets\$(UserSecretsId)\secrets.json
      </UserSecretsFilePath>   
      <UserSecretsFilePath Condition=" '$(OS)' == 'Unix' ">
        $([System.Environment]::GetFolderPath(SpecialFolder.UserProfile))/.microsoft/usersecrets/$(UserSecretsId)/secrets.json
      </UserSecretsFilePath>
    </PropertyGroup>
    <ItemGroup>
      <EmbeddedResource Include="$(UserSecretsFilePath)" Condition="Exists($(UserSecretsFilePath))"/>
    </ItemGroup>
  </Target>
</Project>

It's worth noting that it works on both Windows and Unix/OSX platforms and that because it uses the UserSecretsId property set on the .csproj file, so it can be copied and used "as is" in any project, without any change.

Having this done, every time the Xamarin Forms common project is built and the conditions are meet, the secrets.json file will be embedded into the compiled project.

Read the "secrets.json" file from the App

Now that the secrets.json file has been embedded into the compiled Xamarin Forms common project, we can read his content from our app. As an example of reading from the embedded file, I've used the work done by Andrew Hoefling, well described on his post Xamarin App Configuration: Control Your App Settings from where I've borrowed just a class that I've renamed UserSecretsManager, called from the code behind of the MainPage to retrieve the value of MySecret.

Clearly this just a sample code, on a real app we'll have a mechanism where user secrets will be used to set/ovverride the configuration data on a debug configuration, and a CI/CD pipeline to inject the production configuration data on a release configuration.

How to use UserSecrets in your Xamarin Forms app

To use User Secrets in your Xamarin Forms app you need to:

  1. Init the UserSecrets with Visual Studio (only on your PC) or .NET Core CLI (on your PC or Mac);
  2. Add the Directory.Build.targets file at the root of your Xamarin Forms common project;

Then you can copy and use the UserSecretsManager class to read the secrets.json embedded file content or create something more suited to your needs.

In any case, using the UserSecrets you'll be sure that sensible data won't be inadvertently pushed to the GitHub repository anymore.

About

Demo project that use UserSecrets in a Xamarin Forms App

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages