• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019, Google LLC
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *    * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *    * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *
15  *    * Neither the name of Google LLC nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package com.google.auth.oauth2;
33 
34 import com.google.api.client.util.Preconditions;
35 import com.google.common.base.MoreObjects;
36 import com.google.errorprone.annotations.CanIgnoreReturnValue;
37 import java.io.IOException;
38 import java.util.List;
39 import java.util.Objects;
40 
41 /**
42  * IdTokenCredentials provides a Google Issued OpenIdConnect token. <br>
43  * Use an ID token to access services that require presenting an ID token for authentication such as
44  * Cloud Functions or Cloud Run.<br>
45  * The following Credential subclasses support IDTokens: ServiceAccountCredentials,
46  * ComputeEngineCredentials, ImpersonatedCredentials.
47  *
48  * <p>For more information see <br>
49  * Usage:<br>
50  *
51  * <pre>
52  * String credPath = "/path/to/svc_account.json";
53  * String targetAudience = "https://example.com";
54  *
55  * // For Application Default Credentials (as ServiceAccountCredentials)
56  * // export GOOGLE_APPLICATION_CREDENTIALS=/path/to/svc.json
57  * GoogleCredentials adcCreds = GoogleCredentials.getApplicationDefault();
58  * if (!adcCreds instanceof IdTokenProvider) {
59  *   // handle error message
60  * }
61  *
62  * IdTokenCredentials tokenCredential = IdTokenCredentials.newBuilder()
63  *     .setIdTokenProvider(adcCreds)
64  *     .setTargetAudience(targetAudience).build();
65  *
66  * // for ServiceAccountCredentials
67  * ServiceAccountCredentials saCreds = ServiceAccountCredentials.fromStream(new FileInputStream(credPath));
68  * saCreds = (ServiceAccountCredentials) saCreds.createScoped(Arrays.asList("https://www.googleapis.com/auth/iam"));
69  * IdTokenCredentials tokenCredential = IdTokenCredentials.newBuilder()
70  *     .setIdTokenProvider(saCreds)
71  *     .setTargetAudience(targetAudience).build();
72  *
73  * // for ComputeEngineCredentials
74  * ComputeEngineCredentials caCreds = ComputeEngineCredentials.create();
75  * IdTokenCredentials tokenCredential = IdTokenCredentials.newBuilder()
76  *     .setIdTokenProvider(caCreds)
77  *     .setTargetAudience(targetAudience)
78  *     .setOptions(Arrays.asList(ComputeEngineCredentials.ID_TOKEN_FORMAT_FULL))
79  *     .build();
80  *
81  * // for ImpersonatedCredentials
82  * ImpersonatedCredentials imCreds = ImpersonatedCredentials.create(saCreds,
83  *     "impersonated-account@project.iam.gserviceaccount.com", null,
84  *     Arrays.asList("https://www.googleapis.com/auth/cloud-platform"), 300);
85  * IdTokenCredentials tokenCredential = IdTokenCredentials.newBuilder()
86  *     .setIdTokenProvider(imCreds)
87  *     .setTargetAudience(targetAudience)
88  *     .setOptions(Arrays.asList(ImpersonatedCredentials.INCLUDE_EMAIL))
89  *     .build();
90  *
91  * // Use the IdTokenCredential in an authorized transport
92  * GenericUrl genericUrl = new GenericUrl("https://example.com");
93  * HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(tokenCredential);
94  * HttpTransport transport = new NetHttpTransport();
95  * HttpRequest request = transport.createRequestFactory(adapter).buildGetRequest(genericUrl);
96  * HttpResponse response = request.execute();
97  *
98  * // Print the token, expiration and the audience
99  * System.out.println(tokenCredential.getIdToken().getTokenValue());
100  * System.out.println(tokenCredential.getIdToken().getJsonWebSignature().getPayload().getAudienceAsList());
101  * System.out.println(tokenCredential.getIdToken().getJsonWebSignature().getPayload().getExpirationTimeSeconds());
102  * </pre>
103  */
104 public class IdTokenCredentials extends OAuth2Credentials {
105 
106   private static final long serialVersionUID = -2133257318957588431L;
107 
108   private IdTokenProvider idTokenProvider;
109   private String targetAudience;
110   private List<IdTokenProvider.Option> options;
111 
IdTokenCredentials(Builder builder)112   private IdTokenCredentials(Builder builder) {
113     this.idTokenProvider = Preconditions.checkNotNull(builder.getIdTokenProvider());
114 
115     // target audience can't be used for UserCredentials
116     if (!(this.idTokenProvider instanceof UserCredentials)) {
117       this.targetAudience = Preconditions.checkNotNull(builder.getTargetAudience());
118     }
119 
120     this.options = builder.getOptions();
121   }
122 
123   @Override
refreshAccessToken()124   public AccessToken refreshAccessToken() throws IOException {
125     return this.idTokenProvider.idTokenWithAudience(targetAudience, options);
126   }
127 
getIdToken()128   public IdToken getIdToken() {
129     return (IdToken) getAccessToken();
130   }
131 
132   @Override
hashCode()133   public int hashCode() {
134     return Objects.hash(options, targetAudience);
135   }
136 
137   @Override
toString()138   public String toString() {
139     return MoreObjects.toStringHelper(this).toString();
140   }
141 
142   @Override
equals(Object obj)143   public boolean equals(Object obj) {
144     if (!(obj instanceof IdTokenCredentials)) {
145       return false;
146     }
147     IdTokenCredentials other = (IdTokenCredentials) obj;
148     return Objects.equals(this.idTokenProvider, other.idTokenProvider)
149         && Objects.equals(this.targetAudience, other.targetAudience);
150   }
151 
152   @Override
toBuilder()153   public Builder toBuilder() {
154     return new Builder()
155         .setIdTokenProvider(this.idTokenProvider)
156         .setTargetAudience(this.targetAudience)
157         .setOptions(this.options);
158   }
159 
newBuilder()160   public static Builder newBuilder() {
161     return new Builder();
162   }
163 
164   public static class Builder extends OAuth2Credentials.Builder {
165 
166     private IdTokenProvider idTokenProvider;
167     private String targetAudience;
168     private List<IdTokenProvider.Option> options;
169 
Builder()170     protected Builder() {}
171 
172     @CanIgnoreReturnValue
setIdTokenProvider(IdTokenProvider idTokenProvider)173     public Builder setIdTokenProvider(IdTokenProvider idTokenProvider) {
174       this.idTokenProvider = idTokenProvider;
175       return this;
176     }
177 
getIdTokenProvider()178     public IdTokenProvider getIdTokenProvider() {
179       return this.idTokenProvider;
180     }
181 
182     @CanIgnoreReturnValue
setTargetAudience(String targetAudience)183     public Builder setTargetAudience(String targetAudience) {
184       this.targetAudience = targetAudience;
185       return this;
186     }
187 
getTargetAudience()188     public String getTargetAudience() {
189       return this.targetAudience;
190     }
191 
192     @CanIgnoreReturnValue
setOptions(List<IdTokenProvider.Option> options)193     public Builder setOptions(List<IdTokenProvider.Option> options) {
194       this.options = options;
195       return this;
196     }
197 
getOptions()198     public List<IdTokenProvider.Option> getOptions() {
199       return this.options;
200     }
201 
202     @Override
build()203     public IdTokenCredentials build() {
204       return new IdTokenCredentials(this);
205     }
206   }
207 }
208