Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a sample for CSP partners that demonstrates the secure app mode…
…l. (#6)
- Loading branch information
1 parent
69132ce
commit 12e853e
Showing
10 changed files
with
478 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Secure App Model | ||
|
||
## Cloud Solution Provider (CSP) Sample | ||
|
||
This sample demonstrates how a Cloud Solution Provider partner can utilize the refresh token obtained using the [Partner Consent](../partnerconsent/README.md) sample with the [Partner Center Java SDK](https://docs.microsoft.com/java/partnercenter/overview). | ||
|
||
### Configuration | ||
|
||
The following configurations in the [application.properties](src/main/resources/application.properties) file need to be modified: | ||
|
||
* **keyvault.baseurl** - The base address for the instance of Azure Key Vault where the refresh token has been stored. | ||
* **keyvault.clientId** - The identifier for the Azure AD application that has been allowed access to the instance of Azure Key Vault. | ||
* **keyvault.clientSecret** - The application secret associated with the application configured to access the instance of Azure Key Vault. | ||
* **partnercenter.accountId** - The account identifier, also known as the Azure AD tenant identifier, for the partner. | ||
* **partnercenter.clientId** - The application identifier for the Azure AD application configured for use with the Partner Center API. | ||
* **partnercenter.clientSecret** - The application secret associated with the application configured to access the Partner Center API. | ||
|
||
Please note that in production scenarios we recommend that you use certificate based authentication to access the instance of Azure Key Vault. The [confidential client flow](https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/Confidential-client-applications-flows) has been used in the sample for simplicity. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<groupId>com.microsoft.store.samples.secureappmodel</groupId> | ||
<artifactId>cspsample</artifactId> | ||
<version>1.0.0</version> | ||
<packaging>jar</packaging> | ||
<name>cspsample</name> | ||
<url>http://maven.apache.org</url> | ||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
<dependencies> | ||
<dependency> | ||
<groupId>com.microsoft.azure</groupId> | ||
<artifactId>adal4j</artifactId> | ||
<version>1.6.3</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.microsoft.azure</groupId> | ||
<artifactId>azure-keyvault</artifactId> | ||
<version>1.1.2</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.microsoft.rest</groupId> | ||
<artifactId>client-runtime</artifactId> | ||
<version>1.6.3</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.microsoft.store</groupId> | ||
<artifactId>partnercenter</artifactId> | ||
<version>1.8.1</version> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<resources> | ||
<resource> | ||
<directory>src/main/resources</directory> | ||
</resource> | ||
</resources> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.8.0</version> | ||
<configuration> | ||
<source>1.8</source> | ||
<target>1.8</target> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
69 changes: 69 additions & 0 deletions
69
...cspsample/src/main/java/com/microsoft/store/samples/secureappmodel/cspsample/Program.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="Program.java" company="Microsoft"> | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
package com.microsoft.store.samples.secureappmodel.cspsample; | ||
|
||
import java.util.Properties; | ||
|
||
import com.microsoft.store.partnercenter.IAadLoginHandler; | ||
import com.microsoft.store.partnercenter.IPartner; | ||
import com.microsoft.store.partnercenter.IPartnerCredentials; | ||
import com.microsoft.store.partnercenter.PartnerService; | ||
import com.microsoft.store.partnercenter.extensions.PartnerCredentials; | ||
import com.microsoft.store.partnercenter.models.partners.OrganizationProfile; | ||
import com.microsoft.store.samples.secureappmodel.cspsample.security.SecureLoginHandler; | ||
|
||
public class Program { | ||
/** | ||
* The name of the azure.properties resource file. | ||
*/ | ||
private static final String AZURE_PROPERTIES = "application.properties"; | ||
|
||
/** | ||
* The name of the partnercenter client identifier property. | ||
*/ | ||
private static final String PARTNER_CENTER_CLIENT_ID = "partnercenter.clientId"; | ||
|
||
/** | ||
* Entry point for the console application. | ||
* | ||
* @param args Arguments passed from the command line. | ||
*/ | ||
public static void main(String args[]) | ||
{ | ||
IAadLoginHandler loginHandler; | ||
IPartner partnerOperations; | ||
IPartnerCredentials credentials; | ||
OrganizationProfile profile; | ||
Properties properties; | ||
|
||
try | ||
{ | ||
properties = new Properties(); | ||
|
||
// Load the properties using the azure.properties file found in the resources directory. | ||
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(AZURE_PROPERTIES)); | ||
|
||
loginHandler = new SecureLoginHandler(properties); | ||
|
||
credentials = PartnerCredentials.getInstance().generateByUserCredentials( | ||
properties.getProperty(PARTNER_CENTER_CLIENT_ID), | ||
loginHandler.authenticate(), | ||
loginHandler); | ||
|
||
partnerOperations = PartnerService.getInstance().createPartnerOperations(credentials); | ||
|
||
profile = partnerOperations.getProfiles().getOrganizationProfile().get(); | ||
|
||
System.out.println(profile.getCompanyName()); | ||
|
||
} | ||
catch(Exception ex) | ||
{ | ||
ex.printStackTrace(); | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...in/java/com/microsoft/store/samples/secureappmodel/cspsample/security/IVaultProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="IVaultProvider.java" company="Microsoft"> | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
package com.microsoft.store.samples.secureappmodel.cspsample.security; | ||
|
||
/** | ||
* Represents a secure mechanism for retrieving and store sensitive information. | ||
*/ | ||
public interface IVaultProvider | ||
{ | ||
/** | ||
* Gets the specified value from the vault. | ||
* | ||
* @param secretName Identifier of the value to be retrieved. | ||
* @return The value for the specified secret. | ||
*/ | ||
String getSecret(String secretName); | ||
} |
154 changes: 154 additions & 0 deletions
154
.../java/com/microsoft/store/samples/secureappmodel/cspsample/security/KeyVaultProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="KeyVaultProvider.java" company="Microsoft"> | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
package com.microsoft.store.samples.secureappmodel.cspsample.security; | ||
|
||
import java.net.MalformedURLException; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.Future; | ||
|
||
import com.microsoft.aad.adal4j.AuthenticationContext; | ||
import com.microsoft.aad.adal4j.AuthenticationResult; | ||
import com.microsoft.aad.adal4j.ClientCredential; | ||
import com.microsoft.azure.keyvault.KeyVaultClient; | ||
import com.microsoft.azure.keyvault.KeyVaultClientCustom; | ||
import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials; | ||
|
||
/** | ||
* Provides a secure mechanism for retrieving and store sensitive information using Azure Key Vault. | ||
*/ | ||
public class KeyVaultProvider implements IVaultProvider | ||
{ | ||
/** | ||
* The client used to interact with the Azure Key Vault service. | ||
*/ | ||
private KeyVaultClientCustom client; | ||
|
||
/** | ||
* The vault name, e.g. https://myvault.vault.azure.net | ||
*/ | ||
private String vaultBaseUrl; | ||
|
||
/** | ||
* Initializes a new instance of the {@link KeyVaultProvider} class. | ||
* | ||
* @param vaultBaseUrl The vault name, e.g. https://myvault.vault.azure.net | ||
* @param clientId The identifier of the client requesting the token. | ||
* @param clientSecret The secure secret of the client requesting the token. | ||
*/ | ||
public KeyVaultProvider(String vaultBaseUrl, String clientId, String clientSecret) | ||
{ | ||
client = getKeyVaultClient(clientId, clientSecret); | ||
this.vaultBaseUrl = vaultBaseUrl; | ||
} | ||
|
||
/** | ||
* Gets the specified value from the vault. | ||
* | ||
* @param secretName Identifier of the value to be retrieved. | ||
* @return The value for the specified secret. | ||
*/ | ||
public String getSecret(String secretName) | ||
{ | ||
return client.getSecret(vaultBaseUrl, secretName).value(); | ||
} | ||
|
||
/** | ||
* Stores the specified value in the vault. | ||
* | ||
* @param secretName Identifier of the value to be stored. | ||
* @param value The value to be stored. | ||
*/ | ||
public void setSecret(String secretName, String value) | ||
{ | ||
client.setSecret(vaultBaseUrl, secretName, value); | ||
} | ||
|
||
/** | ||
* Gets an access token from the authority. | ||
* | ||
* @param authorization Address of the authority to issue the token. | ||
* @param resource Identifier of the target resource that is the recipient of the requested token. | ||
* @param clientId The identifier of the client requesting the token. | ||
* @param clientSecret The secure secret of the client requesting the token. | ||
* @return An instance of {@link AuthenticationResult} that contians an access token and refresh token. | ||
* | ||
* @throws ExecutionException {@link ExecutionException} | ||
* @throws InterruptedException {@link InterruptedException} | ||
* @throws MalformedURLException {@link MalformedURLException} | ||
*/ | ||
private AuthenticationResult getAccessToken(String authorization, String resource, String clientId, String clientSecret) | ||
throws ExecutionException, InterruptedException, MalformedURLException | ||
{ | ||
AuthenticationContext authContext; | ||
AuthenticationResult authResult; | ||
ExecutorService service = null; | ||
Future<AuthenticationResult> future; | ||
|
||
try | ||
{ | ||
service = Executors.newFixedThreadPool(1); | ||
authContext = new AuthenticationContext(authorization, true, service); | ||
|
||
future = authContext.acquireToken( | ||
resource, | ||
new ClientCredential( | ||
clientId, | ||
clientSecret), | ||
null); | ||
|
||
authResult = future.get(); | ||
|
||
return authResult; | ||
} | ||
finally | ||
{ | ||
service.shutdown(); | ||
} | ||
} | ||
|
||
/** | ||
* Gets a client that is capable of interacting with the Azure Key Vault service. | ||
* | ||
* @param clientId The identifier of the client requesting the token. | ||
* @param clientSecret The secure secret of the client requesting the token. | ||
* | ||
* @return A client that is capable of interacting with the Azure Key Vault service. | ||
*/ | ||
private KeyVaultClientCustom getKeyVaultClient(String clientId, String clientSecret) | ||
{ | ||
return new KeyVaultClient(new KeyVaultCredentials() | ||
{ | ||
/** | ||
* @param authorization Address of the authority to issue the token. | ||
* @param resource Identifier of the target resource that is the recipient of the requested token, a URL. | ||
* @param scope The scope of the authentication request. | ||
* | ||
* @return Access token to be used with Azure Key Vault operations. | ||
*/ | ||
@Override | ||
public String doAuthenticate(String authorization, String resource, String scope) | ||
{ | ||
AuthenticationResult authResult; | ||
|
||
try | ||
{ | ||
authResult = getAccessToken(authorization, resource, clientId, clientSecret); | ||
|
||
return authResult.getAccessToken(); | ||
} | ||
catch(Exception ex) | ||
{ | ||
ex.printStackTrace(); | ||
} | ||
|
||
return ""; | ||
} | ||
}); | ||
} | ||
} |
Oops, something went wrong.