Skip to content

Commit 74bcd3f

Browse files
dr3sAndres March (vistaprint)jmelinavwoop
authored
Authentication and Authorization (#793)
* Auth * Authentication and Authorization Client sdk authentication, Server Authentication and authorization. * PR Feedback fixes * Updating docs * Pr comments and end to end test fixes * Adding get token check and minor refactoring * changing autovalue to lombok * removed lognet * Authentication and Authorization End to end test PR comments and end to end test with google auth. * list_features_by_ref to use updated core service method. * Fix for failing test after rebase. * Removed boolean conversion. * Added missing fixture dependency. * Corrected overriding yaml for auth, removed redundant echo. * Allow gcloud command to run without exiting tests * Lint error. * Set GOOGLE_APPLICATION_CREDENTIALS for auth testW * Add gcloud sdk installation to auth tests * Add transactions back to projects, revert to AccessManagementService, and make Auth Config generic * Fix typo in core configuration * Update documentation to remove Google terminology * Remove stream specific configuration in e2e tests * Fix linting Co-authored-by: Andres March (vistaprint) <amarch@vistaprint.com> Co-authored-by: Jayanth Kumar M J <treffen.jayanth@gmail.com> Co-authored-by: e10112844 <jayant.mj@vistaprint.com> Co-authored-by: Willem Pienaar <6728866+woop@users.noreply.github.com> Co-authored-by: Willem Pienaar <git@willem.co>
1 parent 8c2201c commit 74bcd3f

36 files changed

+1797
-272
lines changed

.prow/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ presubmits:
157157

158158
- name: test-end-to-end-auth
159159
decorate: true
160-
always_run: false
160+
always_run: true
161161
spec:
162162
containers:
163163
- image: maven:3.6-jdk-11

core/pom.xml

Lines changed: 106 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,56 @@
109109
<groupId>org.apache.logging.log4j</groupId>
110110
<artifactId>log4j-web</artifactId>
111111
</dependency>
112-
<!--compile io.github.lognet:grpc-spring-boot-starter:3.0.2'-->
113-
<dependency>
114-
<groupId>io.github.lognet</groupId>
115-
<artifactId>grpc-spring-boot-starter</artifactId>
116-
</dependency>
112+
<dependency>
113+
<groupId>org.springframework.security</groupId>
114+
<artifactId>spring-security-core</artifactId>
115+
<version>5.3.0.RELEASE</version>
116+
</dependency>
117+
<dependency>
118+
<groupId>org.springframework.security</groupId>
119+
<artifactId>spring-security-config</artifactId>
120+
<version>5.3.0.RELEASE</version>
121+
</dependency>
122+
<dependency>
123+
<groupId>org.springframework.security.oauth</groupId>
124+
<artifactId>spring-security-oauth2</artifactId>
125+
<version>2.4.0.RELEASE</version>
126+
</dependency>
127+
<dependency>
128+
<groupId>org.springframework.security</groupId>
129+
<artifactId>spring-security-oauth2-client</artifactId>
130+
<version>5.3.0.RELEASE</version>
131+
</dependency>
132+
<dependency>
133+
<groupId>org.springframework.security</groupId>
134+
<artifactId>spring-security-web</artifactId>
135+
<version>5.3.0.RELEASE</version>
136+
</dependency>
137+
<dependency>
138+
<groupId>org.springframework.security</groupId>
139+
<artifactId>spring-security-oauth2-resource-server</artifactId>
140+
<version>5.3.0.RELEASE</version>
141+
</dependency>
142+
<dependency>
143+
<groupId>org.springframework.security</groupId>
144+
<artifactId>spring-security-oauth2-jose</artifactId>
145+
<version>5.3.0.RELEASE</version>
146+
</dependency>
147+
<dependency>
148+
<groupId>net.devh</groupId>
149+
<artifactId>grpc-server-spring-boot-starter</artifactId>
150+
<version>2.4.0.RELEASE</version>
151+
</dependency>
152+
<dependency>
153+
<groupId>com.nimbusds</groupId>
154+
<artifactId>nimbus-jose-jwt</artifactId>
155+
<version>8.2.1</version>
156+
</dependency>
157+
<dependency>
158+
<groupId>org.springframework.security</groupId>
159+
<artifactId>spring-security-oauth2-core</artifactId>
160+
<version>5.3.0.RELEASE</version>
161+
</dependency>
117162
<!--compile "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}"-->
118163
<dependency>
119164
<groupId>org.springframework.boot</groupId>
@@ -130,7 +175,6 @@
130175
<groupId>org.springframework.boot</groupId>
131176
<artifactId>spring-boot-configuration-processor</artifactId>
132177
</dependency>
133-
134178
<!--compile "io.grpc:grpc-services:${grpcVersion}"-->
135179
<dependency>
136180
<groupId>io.grpc</groupId>
@@ -146,7 +190,6 @@
146190
<groupId>com.google.protobuf</groupId>
147191
<artifactId>protobuf-java-util</artifactId>
148192
</dependency>
149-
150193
<!--compile 'com.google.guava:guava:26.0-jre'-->
151194
<dependency>
152195
<groupId>com.google.guava</groupId>
@@ -168,7 +211,6 @@
168211
<artifactId>google-api-services-dataflow</artifactId>
169212
<version>v1b3-rev266-1.25.0</version>
170213
</dependency>
171-
172214
<dependency>
173215
<groupId>org.hibernate</groupId>
174216
<artifactId>hibernate-core</artifactId>
@@ -207,19 +249,35 @@
207249
<groupId>io.prometheus</groupId>
208250
<artifactId>simpleclient_servlet</artifactId>
209251
</dependency>
252+
<dependency>
253+
<groupId>com.google.api.client</groupId>
254+
<artifactId>google-api-client-googleapis-auth-oauth</artifactId>
255+
<version>1.2.3-alpha</version>
256+
</dependency>
257+
<dependency>
258+
<groupId>com.auth0</groupId>
259+
<artifactId>jwks-rsa</artifactId>
260+
<version>0.11.0</version>
261+
</dependency>
210262

263+
<dependency>
264+
<groupId>com.auth0</groupId>
265+
<artifactId>java-jwt</artifactId>
266+
<version>3.10.0</version>
267+
</dependency>
268+
269+
<dependency>
270+
<groupId>sh.ory.keto</groupId>
271+
<artifactId>keto-client</artifactId>
272+
<version>0.4.4-alpha.1</version>
273+
</dependency>
211274
<!--testCompile 'com.jayway.jsonpath:json-path-assert:2.2.0'-->
212275
<dependency>
213276
<groupId>com.jayway.jsonpath</groupId>
214277
<artifactId>json-path-assert</artifactId>
215278
<version>2.2.0</version>
216279
<scope>test</scope>
217280
</dependency>
218-
<dependency>
219-
<groupId>org.mockito</groupId>
220-
<artifactId>mockito-core</artifactId>
221-
<scope>test</scope>
222-
</dependency>
223281

224282
<dependency>
225283
<groupId>org.springframework.boot</groupId>
@@ -231,32 +289,50 @@
231289
<artifactId>spring-boot-test-autoconfigure</artifactId>
232290
<scope>test</scope>
233291
</dependency>
234-
235292
<dependency>
236293
<groupId>javax.xml.bind</groupId>
237294
<artifactId>jaxb-api</artifactId>
238295
</dependency>
239296

240-
<dependency>
241-
<groupId>javax.validation</groupId>
242-
<artifactId>validation-api</artifactId>
243-
<version>2.0.0.Final</version>
244-
</dependency>
245-
<dependency>
246-
<groupId>org.hibernate.validator</groupId>
247-
<artifactId>hibernate-validator</artifactId>
248-
<version>6.1.2.Final</version>
249-
</dependency>
250-
<dependency>
251-
<groupId>org.hibernate.validator</groupId>
252-
<artifactId>hibernate-validator-annotation-processor</artifactId>
253-
<version>6.1.2.Final</version>
254-
</dependency>
255297

256298
<dependency>
257299
<groupId>org.flywaydb</groupId>
258300
<artifactId>flyway-core</artifactId>
259301
<version>${flyway.version}</version>
260302
</dependency>
261-
</dependencies>
303+
<dependency>
304+
<groupId>javax.validation</groupId>
305+
<artifactId>validation-api</artifactId>
306+
<version>2.0.0.Final</version>
307+
</dependency>
308+
<dependency>
309+
<groupId>org.hibernate.validator</groupId>
310+
<artifactId>hibernate-validator</artifactId>
311+
<version>6.1.2.Final</version>
312+
</dependency>
313+
<dependency>
314+
<groupId>org.hibernate.validator</groupId>
315+
<artifactId>hibernate-validator-annotation-processor</artifactId>
316+
<version>6.1.2.Final</version>
317+
</dependency>
318+
319+
<dependency>
320+
<groupId>org.mockito</groupId>
321+
<artifactId>mockito-core</artifactId>
322+
<version>2.23.0</version>
323+
<scope>test</scope>
324+
</dependency>
325+
<dependency>
326+
<groupId>org.springframework</groupId>
327+
<artifactId>spring-test</artifactId>
328+
<version>5.1.3.RELEASE</version>
329+
<scope>test</scope>
330+
</dependency>
331+
<dependency>
332+
<groupId>org.junit.jupiter</groupId>
333+
<artifactId>junit-jupiter</artifactId>
334+
<version>RELEASE</version>
335+
<scope>test</scope>
336+
</dependency>
337+
</dependencies>
262338
</project>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright 2018-2020 The Feast Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package feast.core.auth.authentication;
18+
19+
import java.util.Map;
20+
import org.springframework.security.authentication.AuthenticationProvider;
21+
import org.springframework.security.core.Authentication;
22+
import org.springframework.security.core.AuthenticationException;
23+
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
24+
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
25+
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider;
26+
27+
/** Json Web Token Authentication Provider used to validate incoming requests to Feast Core. */
28+
public class DefaultJwtAuthenticationProvider implements AuthenticationProvider {
29+
30+
private JwtAuthenticationProvider authProvider;
31+
32+
/**
33+
* @param options String K/V pair of options to initialize the AuthenticationProvider with. Only
34+
* one option is currently configurable, the jwkEndpointURI.
35+
*/
36+
public DefaultJwtAuthenticationProvider(Map<String, String> options) {
37+
// Endpoint used to retrieve certificates to validate JWT token
38+
String jwkEndpointURI = options.get("jwkEndpointURI");
39+
40+
// Provide a custom endpoint to retrieve certificates
41+
authProvider =
42+
new JwtAuthenticationProvider(NimbusJwtDecoder.withJwkSetUri(jwkEndpointURI).build());
43+
authProvider.setJwtAuthenticationConverter(new JwtAuthenticationConverter());
44+
}
45+
46+
/**
47+
* Authenticate a request based on its Spring Security Authentication object
48+
*
49+
* @param authentication Authentication object which contains a JWT to validate
50+
* @return Returns the same authentication object after authentication
51+
*/
52+
@Override
53+
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
54+
return authProvider.authenticate(authentication);
55+
}
56+
57+
@Override
58+
public boolean supports(Class<?> aClass) {
59+
return authProvider.supports(aClass);
60+
}
61+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright 2018-2020 The Feast Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package feast.core.auth.authorization;
18+
19+
import org.springframework.security.core.Authentication;
20+
21+
/**
22+
* AuthorizationProvider is the base interface that each AuthorizationProvider needs to implement in
23+
* order to authorize requests to Feast Core
24+
*/
25+
public interface AuthorizationProvider {
26+
27+
/**
28+
* Validates whether a user is allowed access to the project
29+
*
30+
* @param project Name of the Feast project
31+
* @param authentication Spring Security Authentication object
32+
* @return AuthorizationResult result of authorization query
33+
*/
34+
AuthorizationResult checkAccess(String project, Authentication authentication);
35+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright 2018-2020 The Feast Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package feast.core.auth.authorization;
18+
19+
import java.util.Optional;
20+
import javax.annotation.Nullable;
21+
import lombok.AllArgsConstructor;
22+
import lombok.Getter;
23+
24+
/**
25+
* Implementation of AuthorizationProvider will return AuthorizationResult after validating incoming
26+
* requests to Feast Core. AuthorizationResult provides methods to check if user is authorized to
27+
* perform an action or not.
28+
*/
29+
@Getter
30+
@AllArgsConstructor
31+
public class AuthorizationResult {
32+
33+
/**
34+
* Method to create AuthorizationResult Object.
35+
*
36+
* @param allowed True If user is authorized, False otherwise.
37+
* @param failureReason Reason for authorization failure, if any
38+
* @return AuthorizationResult Object.
39+
*/
40+
public static AuthorizationResult create(
41+
@Nullable boolean allowed, @Nullable String failureReason) {
42+
return new AuthorizationResult(allowed, Optional.ofNullable(failureReason));
43+
}
44+
45+
/**
46+
* Method to create failed AuthorizationResult Object.
47+
*
48+
* @param failureReason Reason for authorization failure, if any or Null
49+
* @return AuthorizationResult Object.
50+
*/
51+
public static AuthorizationResult failed(@Nullable String failureReason) {
52+
return new AuthorizationResult(false, Optional.ofNullable(failureReason));
53+
}
54+
55+
/**
56+
* Method to create Success AuthorizationResult Object.
57+
*
58+
* @return AuthorizationResult Object.
59+
*/
60+
public static AuthorizationResult success() {
61+
return new AuthorizationResult(true, Optional.empty());
62+
}
63+
64+
private boolean allowed;
65+
private Optional<String> failureReason;
66+
}

0 commit comments

Comments
 (0)