Hero Banner

Key Resources and Guides

Find key resources and guides that you can accelerate implementations

Reply
Microsoft

CSP and CPV secure application sample codes

CSP sample application and CPV sample application as attached.

10 REPLIES 10
Level 1 Contributor

Re: CSP and CPV secure application sample codes

Hello @Nelson_Lin ,

I'm trying to implement a solution without the Key Vault but failed multiple times.

So my question: Is it possible to write an application without Key Vault / how can I replace all the calls to the Key Vault?

Thank you

Klaus

Ray Level 1 Contributor
Level 1 Contributor

Re: CSP and CPV secure application sample codes

Yes, it's possible since from what I can tell, all you are storing in the Key Vault is a Key-Value pair.  I was able to store those values in the web.config file, and it seemed to work fine for me.

Level 1 Contributor

Re: CSP and CPV secure application sample codes

Hi @Ray,

okay, I'm still having some issues do you think you could give me your sample code?

Microsoft

Re: CSP and CPV secure application sample codes

Hi @KlausPruenster

It is possible to develop a solution that does not require Azure Key Vault. However, I would like to mention that is highly recommended that you leverage a solution that provides similar protection that you get with Azure Key Vault. It is not recommended that you store the application secret and refresh token values in the configuration files. With respect to the Cloud Solution Provider sample the secret was stored in the configuration because that is a sample, and we wanted to make sure the work required to get started with the sample was minmized. 

When you are working with the samples, you will want to look at LoginToPartnerCenter function and replace the respective calls to Azure Key Vault with whatever is appropriate for your solution. 


Isaiah Williams
Cloud Technology Strategist | US – One Commercial Partner
Level 1 Contributor

Re: CSP and CPV secure application sample codes

Hi @idwilliams,

what I tried so far is this:

 

public static async Task<Tuple<string, DateTimeOffset>> LoginToPartnerCenter(string tenantId)
{
	KeyVaultProvider provider = new KeyVaultProvider();
	//var refreshToken = await provider.GetSecretAsync(tenantId);

	var refreshToken = await AuthorizationUtilities.GetADAppToken("https://login.microsoftonline.com/" + tenantId,
																  "https://api.partnercenter.microsoft.com",
																  CSPApplicationId,
																  CSPApplicationSecret);

	var token = await AuthorizationUtilities.GetAADTokenFromRefreshToken("https://login.microsoftonline.com/" + tenantId,
																		 "https://api.partnercenter.microsoft.com",
																		 CSPApplicationId,
																		 CSPApplicationSecret,
																		 refreshToken["access_token"].ToString());

	return new Tuple<string, DateTimeOffset>(token["access_token"].ToString(), DateTimeOffset.UtcNow + TimeSpan.FromTicks(long.Parse(token["expires_on"].ToString())));
}

The first request works, I get a token in the variable refreshToken.

Executing the AuthorizationUtilities.GetAADTokenFromRefreshToken function i get this result:

{"error":"invalid_grant","error_description":"AADSTS9002313: Invalid request. Request is malformed or invalid.\r\nTrace ID: ..............\r\nCorrelation ID: ...............\r\nTimestamp: 2019-02-26 16:38:16Z","error_codes":[9002313],"timestamp":"2019-02-26 16:38:16Z","trace_id":"..........","correlation_id":"..........."}

Do you have any idea where I'm making the mistake here?

 

Microsoft

Re: CSP and CPV secure application sample codes

Hi @KlausPruenster,

The GetADAppToken method perform app only authentication, and it does not return a refresh token. So, you are getting the invalid grant error because you are using an access token instead of a refresh token. With the samples we have provide the refresh token value is obtained using the partner consent sample. It is a web application that leverages Azure Active Directory for authentication. Once you successfully authenticate it requests an access token, the response for that request will include the refresh token value. That value is then stored in Azure Key Vault, and it will be used for future operations to request access tokens.

You can simplify this process by using the PowerShell to obtain the refresh token. For more information on how to accomplish this see Partner Center PowerShell | Secure App Model. You will want to capture the refresh token, store it somewhere secure, and then modify your code to look something like the following 

public static async Task<Tuple<string, DateTimeOffset>> LoginToPartnerCenter(string tenantId)
{
    // Do not hard code the refresh token value.  
    // It should be obtained from a secure location.
    string refreshToken = "REFRESH-TOKEN-VALUE-HERE";

    Newtonsoft.Json.Linq.JObject token = await AuthorizationUtilities.GetAADTokenFromRefreshToken(
        "https://login.microsoftonline.com/" + tenantId,
        "https://api.partnercenter.microsoft.com",
        CSPApplicationId,
        CSPApplicationSecret,
        refreshToken);

    return new Tuple<string, DateTimeOffset>(token["access_token"].ToString(), DateTimeOffset.UtcNow + TimeSpan.FromTicks(long.Parse(token["expires_on"].ToString())));
}

 


Isaiah Williams
Cloud Technology Strategist | US – One Commercial Partner
Level 1 Contributor

Re: CSP and CPV secure application sample codes

Hello @idwilliams ,

thank you so much for your help. Somehow I missed the fact of the second solution where the refresh token is collected hence I didn't understand where this token is coming fromSmiley Happy

But there is one more question left: I'm working on a service to service program, and the solution you implemented requires a UI to get the refresh token. Is there a way to request a refresh token without any user interaction?

Thank you

Klaus

Microsoft

Re: CSP and CPV secure application sample codes

Hi @KlausPruenster,

You will not be able to automate the entire process because of the requirement for multi-factor authentication. That requirement will require an interactive component such as providing an access code from an authenticator application. With this said the generation of the refresh token could be a one time operation depending on how it is generated. 


Isaiah Williams
Cloud Technology Strategist | US – One Commercial Partner
Ray Level 1 Contributor
Level 1 Contributor

Re: CSP and CPV secure application sample codes

Hi @KlausPruenster,

I hope Isaiah Williams answered most of your questions.  Do you still require sample code?  I used PowerShell to generate the refresh token as described in the link that Isaiah posted as I could not generate it automatically through code as he mentioned.  I then modified my REST call to obtain the access token to make my other calls.  I would also concur with Isaiah that you should store the refresh token in Azure Key Vault.  I was able to make my program work with both (i.e. Azure Key Vault and just storing it in a configuration file), so my previous post was just to say it's possible but probably not best practice.

Highlighted
Level 1 Contributor

Re: CSP and CPV secure application sample codes

Hi @Ray,

yes, @idwilliams  answered all my questions so I won't require your example codeRobot Happy.

Thank you both! You helped me a lot!Smiley Very Happy