Getting RBR JWT Token by external token
Using TokenManager for getting external or RBR token
New ability has been added to the Identity Server that allow getting RBR token by user id (see details below).
For using this feature we need use RedBox.Testing.ApiTokenManager.NetFx library (target framework .NET Framework 4.6.1).
Whole solution including TokenManager and example see in attachment.
Before build solution you have to restore all packages (attached solution doesn't include binaries).
You can do it via VisualStudio UI or Package Manager Console (command Update-Package) or using direct NuGet in console (nuget install packages.config
)
See details here.
Note! Also source code accessible as part AutomationTests repository (see folder ApiToken).
The key class is RedBox.Testing.ApiTokenManager.NetFx.TokenManager. Instance can be created via parameterless constructor with default options (using Azure AD as external identity provider). Also possible specify custom provider via passing options in overloaded constructor.
There are 3 public methods:
InitialiseUser
/// <summary> /// Initialises relation between user id and external account via auth2 protocol. /// </summary> /// <param name="userId">The testing user identifier. It's separate independent identifier. No any connection to RBR user identifier.</param> /// <returns>The external access token (JWT token).</returns> public async Task<string> InitialiseUser(string userId)
GetExternalTokenForUser
/// <summary> /// Gets the external access token by user id. /// </summary> /// <param name="userId">The testing user identifier. It's separate independent identifier. No any connection to RBR user identifier.</param> /// <returns>The external access token (JWT token).</returns> /// <exception cref="System.Exception">Token Expired. Please reinitialize manually</exception> public async Task<string> GetExternalTokenForUser(string userId)
GetRBRTokenForUser
/// <summary> /// Gets the RBR access token by testing user id. /// </summary> /// <param name="userId">The testing user identifier. It's separate independent identifier. No any connection to RBR user identifier.</param> /// <param name="idp">Identity provider</param> /// <param name="silent">if set to <c>true</c> for silent token fetching.</param> /// <returns>The RBR JWT access token.</returns> /// <exception cref="System.Exception">No cached token found or token has expired - please refresh the token interactively</exception> public async Task<TokenResponse> GetRBRTokenForUser(string userId, string idp, bool silent = true)
For getting external or RBR access token we need only testing user id. How initialize testing user using RBR Azure AD see below.
Be sure that Identity Server already ran. It's necessary for fetching RBR access token.
// create token manager by default options var tokenManager = new TokenManager(); // use already initialized testing user var userId = 888; // fetch external JWT access token string externalToken = await tokenManager.GetExternalTokenForUser(userid); // use "aad" authentication scheme var idp = "aad"; // fetch RBR JWT access token string rbrToken = await tokenManager.GetRBRTokenForUser(userid, idp);
Now we can use RBR token for access to protected resources via bearer token
string bearerToken = "Bearer " + rbrToken;
Just use it as value for Authorization http header
Important! If you need generate rbr token for some identity server on Azure env you need do 2 additional steps:
1) Setup correct 'rbrAuthority' property in App.config. E.g. we use dev-vm-iy1.westeurope.cloudapp.azure.com env then we need put 'http://dev-vm-iy1.westeurope.cloudapp.azure.com:5000' in rbrAuthority
<add key="rbrAuthority" value="http://dev-vm-iy1.westeurope.cloudapp.azure.com:5000" />
2) Enshure that correct issuer uri (Auth__IssuerUri) put in identity server settings. E.g. for dev-vm-iy1.westeurope.cloudapp.azure.com env correct value is 'http://dev-vm-iy1.westeurope.cloudapp.azure.com:5000'.
It should be configured in /opt/rbr/DevOps/Dockerfiles/RedBox.IdentityServer/env_vars.txt file on env. It should looks like
Auth__IssuerUri=http://dev-vm-iy1.westeurope.cloudapp.azure.com:5000
Example of using TokenManager
In attached solution we have separate console app with example of using TokenManger. See RedBox.Testing.ApiTokenManager.TokenGenerator project.
using System; using RedBox.Testing.ApiTokenManager.NetFx; namespace RedBox.Testing.ApiTokenManager.TokenGenerator { public class Program { static void Main() { // create token manager by default options var tokenManager = new TokenManager(); Console.WriteLine("Enter userid:"); var userid = Console.ReadLine(); Console.WriteLine("Enter idp:"); var idp = Console.ReadLine(); // initialize testing user and fetch init token var token = tokenManager.InitialiseUser(userid).GetAwaiter().GetResult(); Console.WriteLine(); Console.WriteLine($"Token initialised: {token}"); // fetch external token by separate command (in this case it'll be the same as init token) var newToken = tokenManager.GetExternalTokenForUser(userid).GetAwaiter().GetResult(); Console.WriteLine(); Console.WriteLine($"External Token retrieved: {newToken}"); // fetch RBR JWT token var rbrToken = tokenManager.GetRBRTokenForUser(userid, idp).GetAwaiter().GetResult(); Console.WriteLine(); Console.WriteLine($"RBR Token retrieved: {rbrToken.ErrorDescription ?? rbrToken.AccessToken}"); Console.ReadLine(); } } }
Be sure that Identity Server already ran. It's necessary for fetching RBR access token.
Example of full console output
Initialize testing user via RBR Azure AD
First of all we need run InitialiseUser method of TaskManager for initiate setuping test user by specified user id.
We can do it via example described above. We need just this part
// create token manager by default options var tokenManager = new TokenManager(); Console.WriteLine("Enter userid:"); var userid = Console.ReadLine(); // initialize testing user and fetch init token var token = tokenManager.InitialiseUser(userid).GetAwaiter().GetResult();
If we enter new user id then we see next output
Let's do all this instruction and go to https://microsoft.com/devicelogin via browser
Code each time is different. You have to enter code generated especially for your case.
You'll see next page
Enter your code
Continue device login by Localhost Auth Automation application
Bind some account to user id entered before.
That's all what we need! Now we can use defined earlier testing user id for getting access tokens - you only need to do the devicelogin step once per userid to begin with - then after that for the duration of the token's lifetime it will not need any UI so it can be used in automated tests (e.g on the build server).
In our example user id is 888 but use the user's real userid e.g. callcentreuser1@redeboxdev.onmicrosoft.com
Additional Info
The token is cached in encrypted cloud storage keyed on the userid - that token will have an expiry and you may find that when it's expired you need to rerun the process manually to get a fresh token for that userid - watch out for token expiry in the build output when running automated tests that use the token.