Skip to content

Commit

Permalink
feat: support OIDC credentials provider into default credentials prov…
Browse files Browse the repository at this point in the history
…ider chain.
  • Loading branch information
PanPanZou committed Sep 4, 2024
1 parent 8929961 commit d8e3680
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void GetCredentialFileAlibabaCloudCredentialWithAKType()
var defaultCredentialProvider = new DefaultCredentialProvider(profile, null);
TestHelper.CreateIniFileWithAkType();

var credential = (BasicCredentials) defaultCredentialProvider.GetAlibabaCloudClientCredential();
var credential = (BasicCredentials)defaultCredentialProvider.GetAlibabaCloudClientCredential();

TestHelper.DeleteIniFile();

Expand All @@ -81,14 +81,18 @@ Use credential chains
[Fact]
public void GetCredentialFileAlibabaCloudCredentialWithAKTypeButAKIsEmpty()
{
Environment.SetEnvironmentVariable("ALIBABA_CLOUD_ROLE_ARN", null);
Environment.SetEnvironmentVariable("ALIBABA_CLOUD_OIDC_PROVIDER_ARN", null);
Environment.SetEnvironmentVariable("ALIBABA_CLOUD_OIDC_TOKEN_FILE", null);

var profile = DefaultProfile.GetProfile();
profile.DefaultClientName = "default";
var defaultCredentialProvider = new DefaultCredentialProvider(profile, null);
TestHelper.CreateIniFileWithAkTypeWithEmptyAK();

var exception = Assert.Throws<ClientException>(() =>
{
var credential = (BasicCredentials) defaultCredentialProvider.GetAlibabaCloudClientCredential();
var credential = (BasicCredentials)defaultCredentialProvider.GetAlibabaCloudClientCredential();
});

TestHelper.DeleteIniFile();
Expand Down Expand Up @@ -136,7 +140,7 @@ public void GetCredentialFileAlibabaCloudCredentialWithEcsRamRole()
mockDefaultCredentialProvider.Setup(x => x.GetHomePath()).Returns(mockHomePath);

var defaultCredentialProvider = mockDefaultCredentialProvider.Object;
var credential = (InstanceProfileCredentials) defaultCredentialProvider.GetAlibabaCloudClientCredential();
var credential = (InstanceProfileCredentials)defaultCredentialProvider.GetAlibabaCloudClientCredential();

TestHelper.DeleteIniFile();
Assert.NotNull(credential);
Expand All @@ -157,7 +161,7 @@ public void GetCredentialFileAlibabaCloudCredentialWithFileAndAkExist()

var defaultCredentialProvider = new DefaultCredentialProvider(profile, null);

var credential = (BasicCredentials) defaultCredentialProvider.GetCredentialFileAlibabaCloudCredential();
var credential = (BasicCredentials)defaultCredentialProvider.GetCredentialFileAlibabaCloudCredential();

TestHelper.DeleteIniFile();
Assert.NotNull(credential);
Expand Down Expand Up @@ -225,7 +229,7 @@ public void GetCredentialFileAlibabaCloudCredentialWithRamRole()

var defaultCredentialProvider = mockDefaultCredentialProvider.Object;

var credential = (InstanceProfileCredentials) defaultCredentialProvider.GetAlibabaCloudClientCredential();
var credential = (InstanceProfileCredentials)defaultCredentialProvider.GetAlibabaCloudClientCredential();

TestHelper.DeleteIniFile();
Assert.NotNull(credential);
Expand Down Expand Up @@ -253,7 +257,7 @@ public void GetCredentialFileAlibabaCloudCredentialWithRsaKey()

var defaultCredentialProvider = mockDefaultCredentialProvider.Object;

var credential = (BasicSessionCredentials) defaultCredentialProvider.GetAlibabaCloudClientCredential();
var credential = (BasicSessionCredentials)defaultCredentialProvider.GetAlibabaCloudClientCredential();

TestHelper.DeleteIniFile();
Assert.NotNull(credential);
Expand All @@ -272,7 +276,7 @@ public void GetEnvironmentAlibabaCloudCredentialUseChain()
TestHelper.InitializeEnvironmentValue();

var defaultCredentialProvider = new DefaultCredentialProvider(profile, null);
var credential = (BasicCredentials) defaultCredentialProvider.GetAlibabaCloudClientCredential();
var credential = (BasicCredentials)defaultCredentialProvider.GetAlibabaCloudClientCredential();

Assert.NotNull(credential);
Assert.Equal("ACCESS_KEY_ID", credential.GetAccessKeyId());
Expand All @@ -293,7 +297,7 @@ public void GetEnvironmentAlibabaCloudCredentialWithEnvAKTest()
TestHelper.InitializeEnvironmentValue();

var defaultCredentialProvider = new DefaultCredentialProvider(profile, null);
var credential = (BasicCredentials) defaultCredentialProvider.GetEnvironmentAlibabaCloudCredential();
var credential = (BasicCredentials)defaultCredentialProvider.GetEnvironmentAlibabaCloudCredential();

Assert.NotNull(credential);
Assert.Equal("ACCESS_KEY_ID", credential.GetAccessKeyId());
Expand All @@ -309,7 +313,7 @@ public void GetEnvironmentAlibabaCloudCredentialWithEnvAKTest()
public void GetEnvironmentClientCredentialWithoutAKTest()
{
var defaultCredentialProvider = new DefaultCredentialProvider();
var credential = (BasicCredentials) defaultCredentialProvider.GetEnvironmentAlibabaCloudCredential();
var credential = (BasicCredentials)defaultCredentialProvider.GetEnvironmentAlibabaCloudCredential();
Assert.Null(credential);
}

Expand Down Expand Up @@ -502,5 +506,32 @@ public void GetRsaKeyPairAlibabaCloudCredentialWithException()

Assert.Equal("Missing required variable option for 'default Client'", exception.Message);
}

[Fact]
public void GetOIDCAlibabaCloudCredential()
{
var profile = DefaultProfile.GetProfile();
var defaultCredentialProvider = new DefaultCredentialProvider(profile, null);
Assert.Null(defaultCredentialProvider.GetOIDCAlibabaCloudCredential());

Environment.SetEnvironmentVariable("ALIBABA_CLOUD_ROLE_ARN", "role_arn");
Environment.SetEnvironmentVariable("ALIBABA_CLOUD_OIDC_PROVIDER_ARN", "oidc_provider_arn");
Environment.SetEnvironmentVariable("ALIBABA_CLOUD_OIDC_TOKEN_FILE", "oidc_token_file");

var mockDefaultCredentialProvider = new Mock<DefaultCredentialProvider>(profile, null);
var basicSessionCredential = new BasicSessionCredentials("fakeak", "fakeaks", "fakesessiontoken", 4000);
mockDefaultCredentialProvider.Setup(p => p.GetOIDCAlibabaCloudCredential()).Returns(basicSessionCredential);
defaultCredentialProvider = mockDefaultCredentialProvider.Object;
var credential = (BasicSessionCredentials)defaultCredentialProvider.GetAlibabaCloudClientCredential();
Assert.NotNull(credential);
Assert.Equal("fakeak", credential.GetAccessKeyId());
Assert.Equal("fakeaks", credential.GetAccessKeySecret());
Assert.Equal("fakesessiontoken", credential.GetSessionToken());
Assert.False(credential.WillSoonExpire());

Environment.SetEnvironmentVariable("ALIBABA_CLOUD_ROLE_ARN", null);
Environment.SetEnvironmentVariable("ALIBABA_CLOUD_OIDC_PROVIDER_ARN", null);
Environment.SetEnvironmentVariable("ALIBABA_CLOUD_OIDC_TOKEN_FILE", null);
}
}
}
16 changes: 16 additions & 0 deletions aliyun-net-sdk-core/Auth/Provider/DefaultCredentialProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* under the License.
*/

using System;
using System.IO;

using Aliyun.Acs.Core.Exceptions;
Expand All @@ -39,6 +40,8 @@ public class DefaultCredentialProvider
private string regionId;
private string roleArn;
private string roleName;
private string oidcProviderArn;
private string oidcTokenFile;

public DefaultCredentialProvider()
{
Expand All @@ -55,6 +58,9 @@ AlibabaCloudCredentialsProvider alibabaCloudCredentialProvider
credentialFileLocation = EnvironmentUtil.GetEnvironmentCredentialFile();
roleName = EnvironmentUtil.GetEnvironmentRoleName();
defaultProfile = profile;
roleArn = EnvironmentUtil.GetEnvironmentRoleArn();
oidcProviderArn = EnvironmentUtil.GetEnvironmentOIDCProviderArn();
oidcTokenFile = EnvironmentUtil.GetEnvironmentOIDCTokenFile();
this.alibabaCloudCredentialProvider = alibabaCloudCredentialProvider;
}

Expand All @@ -75,6 +81,7 @@ AlibabaCloudCredentialsProvider alibabaCloudCredentialsProvider
public AlibabaCloudCredentials GetAlibabaCloudClientCredential()
{
var credential = GetEnvironmentAlibabaCloudCredential() ??
GetOIDCAlibabaCloudCredential() ??
GetCredentialFileAlibabaCloudCredential() ??
GetInstanceRamRoleAlibabaCloudCredential();

Expand All @@ -86,6 +93,15 @@ public AlibabaCloudCredentials GetAlibabaCloudClientCredential()
return credential;
}

internal virtual AlibabaCloudCredentials GetOIDCAlibabaCloudCredential()
{
if (string.IsNullOrEmpty(oidcProviderArn) || string.IsNullOrEmpty(roleArn) || string.IsNullOrEmpty(oidcTokenFile))
{
return null;
}
return new OIDCCredentialsProvider(roleArn, oidcProviderArn, oidcTokenFile, null, null).GetCredentials();
}

public AlibabaCloudCredentials GetEnvironmentAlibabaCloudCredential()
{
if (null == accessKeyId || null == accessKeySecret)
Expand Down
9 changes: 7 additions & 2 deletions aliyun-net-sdk-core/Auth/Provider/OIDCCredentialsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public OIDCCredentialsProvider(string roleArn, string oidcProviderArn, string oi

if (string.IsNullOrEmpty(RoleSessionName))
{
RoleSessionName = "DEFAULT_ROLE_SESSION_NAME_FOR_C#_SDK_V1";
RoleSessionName = GetNewRoleSessionName();
}

if (string.IsNullOrEmpty(regionId))
Expand All @@ -57,6 +57,11 @@ public OIDCCredentialsProvider(string roleArn, string oidcProviderArn, string oi
durationSeconds = 3600;
}

public static string GetNewRoleSessionName()
{
return "aliyun-net-sdk-" + DateTime.UtcNow.currentTimeMillis();
}

public string InvokeAssumeRoleWithOIDC()
{
var queries = new Dictionary<string, string>
Expand Down Expand Up @@ -138,7 +143,7 @@ internal static BasicSessionCredentials ParseCredentials(string body, long durat
else if (map.ContainsKey("Credentials"))
{
var credentialsJson = JsonConvert.SerializeObject(DictionaryUtil.Get(map, "Credentials"));
var credentials = JsonConvert.DeserializeObject<Dictionary<string, string>> (credentialsJson);
var credentials = JsonConvert.DeserializeObject<Dictionary<string, string>>(credentialsJson);
var accessKeyId = DictionaryUtil.Get(credentials, "AccessKeyId");
var accessKeySecret = DictionaryUtil.Get(credentials, "AccessKeySecret");
var securityToken = DictionaryUtil.Get(credentials, "SecurityToken");
Expand Down
2 changes: 2 additions & 0 deletions aliyun-net-sdk-core/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
Expand Down Expand Up @@ -30,3 +31,4 @@
//
[assembly: AssemblyVersion("1.5.11.0")]
[assembly: AssemblyFileVersion("1.5.11.0")]
[assembly: InternalsVisibleTo("Aliyun.Net.Credentials.UnitTests")]
18 changes: 18 additions & 0 deletions aliyun-net-sdk-core/Utils/EnvironmentUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public class EnvironmentUtil
private static readonly string ENV_REGION_ID = "ALIBABA_CLOUD_REGION_ID";
private static readonly string ENV_CREDENTIAL_FILE = "ALIBABA_CLOUD_CREDENTIALS_FILE";
private static readonly string ENV_ROLE_NAME = "ALIBABA_CLOUD_ECS_METADATA";
private static readonly string ENV_ROLE_ARN = "ALIBABA_CLOUD_ROLE_ARN";
private static readonly string ENV_OIDC_PROVIDER_ARN = "ALIBABA_CLOUD_OIDC_PROVIDER_ARN";
private static readonly string ENV_OIDC_TOKEN_FILE = "ALIBABA_CLOUD_OIDC_TOKEN_FILE";

public static string GetHomePath()
{
Expand Down Expand Up @@ -68,6 +71,21 @@ public static string GetEnvironmentRoleName()
return Environment.GetEnvironmentVariable(ENV_ROLE_NAME) ?? null;
}

public static string GetEnvironmentRoleArn()
{
return Environment.GetEnvironmentVariable(ENV_ROLE_ARN) ?? null;
}

public static string GetEnvironmentOIDCProviderArn()
{
return Environment.GetEnvironmentVariable(ENV_OIDC_PROVIDER_ARN) ?? null;
}

public static string GetEnvironmentOIDCTokenFile()
{
return Environment.GetEnvironmentVariable(ENV_OIDC_TOKEN_FILE) ?? null;
}

public static string GetComposedPath(string homePath, string slash)
{
return homePath + slash + ".alibabacloud" + slash + "credentials.ini";
Expand Down

0 comments on commit d8e3680

Please sign in to comment.