Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Google.Apis.Auth.OAuth2.ImpersonatedCredentials #1312

Closed
salrashid123 opened this issue Nov 25, 2018 · 13 comments
Closed

Implement Google.Apis.Auth.OAuth2.ImpersonatedCredentials #1312

salrashid123 opened this issue Nov 25, 2018 · 13 comments
Assignees
Labels
type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design.

Comments

@salrashid123
Copy link

Allows one user or service account to impersonate another using iamcredentials api.

Impersonated Credentials allows credentials issued to a user or
service account to impersonate another. The target service account must
grant the originating credential principal the
`Service Account Token Creator`_ IAM role:
For more information about Token Creator IAM role and
IAMCredentials API, see

I don't know dotnet well but took a shot at implementation here which works:

Google.Apis.Auth.OAuth2.ImpersonatedCredentials.cs


THe snippet above does work with a client like this in the sense i get the correct derived access_token

Stream jsonKey = System.IO.File.OpenRead("mineral-minutia-820-83b3ce7dcddb.json");
GoogleCredential sourceCredentials = GoogleCredential.FromStream(jsonKey);

string targetPrincipal = "impersonated-account@fabled-ray-104117.iam.gserviceaccount.com";
string[] scopes = { "https://www.googleapis.com/auth/devstorage.read_only" };
string[] delegates = { };
int lifetime = 3600;

GoogleCredential targetCredentials = GoogleCredential.ToImpersonatedCredentials(
                sourceCredentials,
                targetPrincipal,
                scopes,
                delegates,
                lifetime
);

string accessToken = await (targetCredentials as ITokenAccess).GetAccessTokenForRequestAsync();
Console.WriteLine(accessToken);

ImpersonatedCredential impersonatedCredential = new ImpersonatedCredential(new ImpersonatedCredential.Initializer
            {
                SourceCredential = sourceCredentials,
                TargetPrincipal = targetPrincipal,
                Scopes = scopes,
                Delegates = delegates,
                Lifetime = lifetime
            });

accessToken = await (impersonatedCredential as ITokenAccess).GetAccessTokenForRequestAsync();
Console.WriteLine(accessToken);

but i don't know enough about dotnet package references to allow passing it into

var client = StorageClient.Create(targetCredentials);
foreach (var obj in client.ListBuckets("mineral-minutia-820"))
{
    Console.WriteLine(obj.Name);
}

If you want to set it up, here are some gcloud commands to setup impersonation credentials:

Setup: https://gist.github.com/salrashid123/d3f4055496ffcfa18221aadd9c14e7e9


its already implemented or pending for several other languages:

ref:

@JustinBeckwith JustinBeckwith added the triage me I really want to be triaged. label Nov 26, 2018
@chrisdunelm chrisdunelm self-assigned this Nov 27, 2018
@chrisdunelm chrisdunelm added type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design. and removed triage me I really want to be triaged. labels Nov 27, 2018
@Zunair
Copy link

Zunair commented Apr 15, 2019

@NinoFloris
Copy link

This would be wonderful for development scenarios

@jskeet
Copy link
Collaborator

jskeet commented Mar 16, 2020

Assigning to Amanda to see whether this is covered by existing auth work and/or other languages.

@amanda-tarafa
Copy link
Contributor

Note to self: impersonated credentials should be OIDC token providers as well.

@amanda-tarafa
Copy link
Contributor

This issue has been moved to the backlog in #1719 . Please refer to BACKLOG.md for more information.

arithmetic1728 added a commit to arithmetic1728/google-api-dotnet-client that referenced this issue Apr 21, 2021
@amanda-tarafa amanda-tarafa reopened this Apr 27, 2021
@amanda-tarafa
Copy link
Contributor

Being adressed in #1838 .

@amanda-tarafa
Copy link
Contributor

@arithmetic1728 not sure why I can't assign this one to you. I'll take a look later.

@amanda-tarafa
Copy link
Contributor

Closing via #1838 and #1874

@amanda-tarafa
Copy link
Contributor

FYI: This has been released on the v1.52.0 of the Google.Apis libraries.

@salrashid123 If you try it out and find any issues, do let us know. Thanks!

FYI: @arithmetic1728 .

@Zunair
Copy link

Zunair commented Jun 15, 2021 via email

@amanda-tarafa
Copy link
Contributor

@Zunair v1.52.0 was released an hour ago roughly and before that the Google.Apis.Auth library didn't support impersonation.

Are you referring to Domain Wide Delegation? That has been supported for a long time, without any issues.

@Zunair
Copy link

Zunair commented Jun 15, 2021

Ah ok, yes I confused it with domain wide delegation.

Thanks!

@salrashid123
Copy link
Author

thx. confirmed it works with storage, oauth2 api library and id token as impersonated creds

        public async Task<string> Run()
        {

            Stream jsonKey = System.IO.File.OpenRead("/path/to/svc.json");

            string targetPrincipal = "impersonated-account@project.iam.gserviceaccount.com";
            //GoogleCredential sourceCredential = GoogleCredential.GetApplicationDefault();
            GoogleCredential sourceCredential = GoogleCredential.FromStream(jsonKey);

            var credential = sourceCredential.Impersonate(new ImpersonatedCredential.Initializer(targetPrincipal)
            {
                DelegateAccounts = new string[] { },
                Scopes = new string[] { "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/devstorage.read_only" },
                Lifetime = TimeSpan.FromHours(1)
            });

            var service = new Oauth2Service(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "Oauth2 Sample",
            });
            Console.WriteLine(service.Userinfo.Get().Execute().Email);

            var targetAudience = "https://myapp-6w42z6vi3q-uc.a.run.app";
            OidcToken oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience(targetAudience).WithTokenFormat(OidcTokenFormat.Standard)).ConfigureAwait(false);

            string token = await oidcToken.GetAccessTokenAsync().ConfigureAwait(false);
            Console.WriteLine(token);

            // b) For Google Cloud APIs:

            var client = StorageClient.Create(credential);
            foreach (var obj in client.ListObjects("fabled-ray-104117", ""))
            {
                Console.WriteLine(obj.Name);
            }
            return null;
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design.
Projects
None yet
Development

No branches or pull requests

7 participants