Skip to content

Commit dd4e53e

Browse files
committed
Enable dual authentication methods
1 parent 535802e commit dd4e53e

File tree

15 files changed

+507
-202
lines changed

15 files changed

+507
-202
lines changed

docs/security.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ for more details.
3636
3737
The authentication would happen on https protocol only. Add the
3838
`authentication:` section in the config file. The default authentication type is
39-
set using `defaultType: "form"` Following types of the authentications are
40-
supported.
39+
set using `defaultTypes: ["form"]`. The first authentication type in `defaultTypes` is prioritized and then falls back to following ones.
40+
Following types of the authentications are supported.
4141

4242
### OAuth/OpenIDConnect
4343

4444
It can be configured as below
4545

4646
```yaml
4747
authentication:
48-
defaultType: "oauth"
48+
defaultTypes: ["oauth"]
4949
oauth:
5050
issuer:
5151
clientId:
@@ -81,6 +81,11 @@ Set the `privilegesField` to retrieve privileges from an OAuth claim.
8181
```
8282
- That also means you need to have a cluster with that routing group.
8383
- It's ok to replicate an existing Trino cluster record with a different name for that purpose.
84+
- If you want to have all users who are authenticated via SSO and are not in the `presetUsers` list be able to view the dashboard and query history, you can set `defaultPrivilege` in the config file:
85+
```yaml
86+
authorization:
87+
defaultPrivilege: "USER"
88+
```
8489

8590
### Form/Basic authentication
8691

@@ -102,7 +107,7 @@ Also provide a random key pair in RSA format.
102107

103108
```yaml
104109
authentication:
105-
defaultType: "form"
110+
defaultTypes: ["form"]
106111
form:
107112
selfSignKeyPair:
108113
privateKeyRsa: <private_key_path>
@@ -115,7 +120,7 @@ LDAP requires both random key pair and config path for LDAP
115120

116121
```yaml
117122
authentication:
118-
defaultType: "form"
123+
defaultTypes: ["form"]
119124
form:
120125
ldapConfigPath: <ldap_config_path>
121126
selfSignKeyPair:

gateway-ha/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,13 @@
323323
<scope>runtime</scope>
324324
</dependency>
325325

326+
<dependency>
327+
<groupId>com.github.docker-java</groupId>
328+
<artifactId>docker-java-api</artifactId>
329+
<version>3.4.2</version>
330+
<scope>test</scope>
331+
</dependency>
332+
326333
<!-- Test deps -->
327334
<dependency>
328335
<groupId>com.h2database</groupId>

gateway-ha/src/main/java/io/trino/gateway/ha/config/AuthenticationConfiguration.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,31 @@
1313
*/
1414
package io.trino.gateway.ha.config;
1515

16+
import java.util.List;
17+
1618
public class AuthenticationConfiguration
1719
{
18-
private String defaultType;
20+
private List<String> defaultTypes;
1921
private OAuthConfiguration oauth;
2022
private FormAuthConfiguration form;
2123

22-
public AuthenticationConfiguration(String defaultType, OAuthConfiguration oauth, FormAuthConfiguration form)
24+
public AuthenticationConfiguration(List<String> defaultTypes, OAuthConfiguration oauth, FormAuthConfiguration form)
2325
{
24-
this.defaultType = defaultType;
26+
this.defaultTypes = defaultTypes;
2527
this.oauth = oauth;
2628
this.form = form;
2729
}
2830

2931
public AuthenticationConfiguration() {}
3032

31-
public String getDefaultType()
33+
public List<String> getDefaultTypes()
3234
{
33-
return this.defaultType;
35+
return this.defaultTypes;
3436
}
3537

36-
public void setDefaultType(String defaultType)
38+
public void setDefaultTypes(List<String> defaultTypes)
3739
{
38-
this.defaultType = defaultType;
40+
this.defaultTypes = defaultTypes;
3941
}
4042

4143
public OAuthConfiguration getOauth()

gateway-ha/src/main/java/io/trino/gateway/ha/config/AuthorizationConfiguration.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ public class AuthorizationConfiguration
1919
private String user;
2020
private String api;
2121
private String ldapConfigPath;
22+
private String defaultPrivilege;
2223

23-
public AuthorizationConfiguration(String admin, String user, String api, String ldapConfigPath)
24+
public AuthorizationConfiguration(String admin, String user, String api, String ldapConfigPath, String defaultPrivilege)
2425
{
2526
this.admin = admin;
2627
this.user = user;
2728
this.api = api;
2829
this.ldapConfigPath = ldapConfigPath;
30+
this.defaultPrivilege = defaultPrivilege;
2931
}
3032

3133
public AuthorizationConfiguration() {}
@@ -69,4 +71,14 @@ public void setLdapConfigPath(String ldapConfigPath)
6971
{
7072
this.ldapConfigPath = ldapConfigPath;
7173
}
74+
75+
public String getDefaultPrivilege()
76+
{
77+
return this.defaultPrivilege;
78+
}
79+
80+
public void setDefaultPrivilege(String defaultPrivilege)
81+
{
82+
this.defaultPrivilege = defaultPrivilege;
83+
}
7284
}

gateway-ha/src/main/java/io/trino/gateway/ha/module/HaGatewayProviderModule.java

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -145,28 +145,39 @@ private LbFormAuthManager getFormAuthManager(HaGatewayConfiguration configuratio
145145
private ChainedAuthFilter getAuthenticationFilters(AuthenticationConfiguration config, Authorizer authorizer)
146146
{
147147
ImmutableList.Builder<ContainerRequestFilter> authFilters = ImmutableList.builder();
148-
String defaultType = config.getDefaultType();
149-
if (oauthManager != null) {
150-
authFilters.add(new LbFilter(
151-
new LbAuthenticator(oauthManager, authorizationManager),
152-
authorizer,
153-
"Bearer",
154-
new LbUnauthorizedHandler(defaultType)));
148+
List<String> authMethods = config.getDefaultTypes();
149+
if (authMethods == null || authMethods.isEmpty()) {
150+
return new ChainedAuthFilter(authFilters.build());
155151
}
156152

157-
if (formAuthManager != null) {
158-
authFilters.add(new LbFilter(
159-
new FormAuthenticator(formAuthManager, authorizationManager),
160-
authorizer,
161-
"Bearer",
162-
new LbUnauthorizedHandler(defaultType)));
153+
for (String authMethod : authMethods) {
154+
switch (authMethod) {
155+
case "oauth" -> {
156+
if (oauthManager != null) {
157+
authFilters.add(new LbFilter(
158+
new LbAuthenticator(oauthManager, authorizationManager),
159+
authorizer,
160+
"Bearer",
161+
new LbUnauthorizedHandler("oauth")));
162+
}
163+
}
164+
case "form" -> {
165+
if (formAuthManager != null) {
166+
authFilters.add(new LbFilter(
167+
new FormAuthenticator(formAuthManager, authorizationManager),
168+
authorizer,
169+
"Bearer",
170+
new LbUnauthorizedHandler("form")));
163171

164-
authFilters.add(new BasicAuthFilter(
165-
new ApiAuthenticator(formAuthManager, authorizationManager),
166-
authorizer,
167-
new LbUnauthorizedHandler(defaultType)));
172+
authFilters.add(new BasicAuthFilter(
173+
new ApiAuthenticator(formAuthManager, authorizationManager),
174+
authorizer,
175+
new LbUnauthorizedHandler("form")));
176+
}
177+
}
178+
default -> {}
179+
}
168180
}
169-
170181
return new ChainedAuthFilter(authFilters.build());
171182
}
172183

gateway-ha/src/main/java/io/trino/gateway/ha/resource/LoginResource.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.google.common.collect.ImmutableList;
1717
import com.google.inject.Inject;
1818
import io.airlift.log.Logger;
19+
import io.trino.gateway.ha.config.HaGatewayConfiguration;
1920
import io.trino.gateway.ha.domain.Result;
2021
import io.trino.gateway.ha.domain.request.RestLoginRequest;
2122
import io.trino.gateway.ha.security.LbFormAuthManager;
@@ -56,10 +57,12 @@ public class LoginResource
5657

5758
private final LbOAuthManager oauthManager;
5859
private final LbFormAuthManager formAuthManager;
60+
private final HaGatewayConfiguration haGatewayConfiguration;
5961

6062
@Inject
61-
public LoginResource(@Nullable LbOAuthManager oauthManager, @Nullable LbFormAuthManager formAuthManager)
63+
public LoginResource(HaGatewayConfiguration haGatewayConfiguration, @Nullable LbOAuthManager oauthManager, @Nullable LbFormAuthManager formAuthManager)
6264
{
65+
this.haGatewayConfiguration = haGatewayConfiguration;
6366
this.oauthManager = oauthManager;
6467
this.formAuthManager = formAuthManager;
6568
}
@@ -173,16 +176,13 @@ else if (oauthManager != null) {
173176
@Produces(MediaType.APPLICATION_JSON)
174177
public Response loginType()
175178
{
176-
String loginType;
177-
if (formAuthManager != null) {
178-
loginType = "form";
179-
}
180-
else if (oauthManager != null) {
181-
loginType = "oauth";
179+
List<String> loginTypes;
180+
if (haGatewayConfiguration.getAuthentication() != null) {
181+
loginTypes = haGatewayConfiguration.getAuthentication().getDefaultTypes();
182182
}
183183
else {
184-
loginType = "none";
184+
loginTypes = List.of("none");
185185
}
186-
return Response.ok(Result.ok("Ok", loginType)).build();
186+
return Response.ok(Result.ok("Ok", loginTypes)).build();
187187
}
188188
}

gateway-ha/src/main/java/io/trino/gateway/ha/security/AuthorizationManager.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ public class AuthorizationManager
2424
{
2525
private final Map<String, UserConfiguration> presetUsers;
2626
private final LbLdapClient lbLdapClient;
27+
private final AuthorizationConfiguration authorizationConfiguration;
2728

2829
public AuthorizationManager(AuthorizationConfiguration configuration,
2930
Map<String, UserConfiguration> presetUsers)
3031
{
3132
this.presetUsers = presetUsers;
33+
this.authorizationConfiguration = configuration;
3234
if (configuration != null && configuration.getLdapConfigPath() != null) {
3335
lbLdapClient = new LbLdapClient(LdapConfiguration.load(configuration.getLdapConfigPath()));
3436
}
@@ -49,6 +51,13 @@ public Optional<String> getPrivileges(String username)
4951
else if (lbLdapClient != null) {
5052
privs = lbLdapClient.getMemberOf(username);
5153
}
52-
return Optional.ofNullable(privs);
54+
55+
if (privs == null || privs.trim().isEmpty()) {
56+
if (authorizationConfiguration != null && authorizationConfiguration.getDefaultPrivilege() != null) {
57+
return Optional.of(authorizationConfiguration.getDefaultPrivilege());
58+
}
59+
return Optional.empty(); // No default privilege if not configured
60+
}
61+
return Optional.of(privs);
5362
}
5463
}

0 commit comments

Comments
 (0)