Skip to content

Commit b9a6fb6

Browse files
committed
Support fallback authenticator for malformed www-authenticate headers
1 parent 4751815 commit b9a6fb6

File tree

6 files changed

+46
-5
lines changed

6 files changed

+46
-5
lines changed

api/src/main/java/com/inrupt/client/auth/ReactiveAuthorization.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
public class ReactiveAuthorization {
4848

4949
private static final Logger LOGGER = LoggerFactory.getLogger(ReactiveAuthorization.class);
50+
private static final String BEARER = "Bearer";
5051

5152
private static final Comparator<Authenticator> comparator = Comparator
5253
.comparing(Authenticator::getPriority)
@@ -64,7 +65,9 @@ public ReactiveAuthorization() {
6465
ReactiveAuthorization.class.getClassLoader());
6566

6667
for (final AuthenticationProvider provider : loader) {
67-
registry.put(provider.getScheme(), provider);
68+
for (final String scheme : provider.getSchemes()) {
69+
registry.put(provider.getScheme(), provider);
70+
}
6871
}
6972
}
7073

@@ -90,7 +93,14 @@ public CompletionStage<Optional<Credential>> negotiate(final Session session, fi
9093
}
9194
}
9295

93-
if (!authenticators.isEmpty()) {
96+
if (authenticators.isEmpty()) {
97+
// Fallback in case of missing or poorly formed www-authenticate header
98+
if (registry.containsKey(BEARER)) {
99+
final Authenticator auth = registry.get(BEARER).getAuthenticator(Challenge.of(BEARER));
100+
LOGGER.debug("Using fallback Bearer authenticator");
101+
return session.authenticate(auth, request, algorithms);
102+
}
103+
} else {
94104
// Use the first authenticator, sorted by priority
95105
authenticators.sort(comparator);
96106
final Authenticator auth = authenticators.get(0);

api/src/main/java/com/inrupt/client/spi/AuthenticationProvider.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import com.inrupt.client.auth.Authenticator;
2424
import com.inrupt.client.auth.Challenge;
2525

26+
import java.util.Set;
27+
2628
/**
2729
* An authentication mechanism that knows how to authenticate over network connections.
2830
*/
@@ -32,9 +34,18 @@ public interface AuthenticationProvider {
3234
* Return the authorization scheme, such as Bearer or DPoP.
3335
*
3436
* @return the authorization scheme
37+
* @deprecated as of Beta3, please use the {@link #getSchemes()} method
3538
*/
39+
@Deprecated
3640
String getScheme();
3741

42+
/**
43+
* Return the set of supported authorization schemes, such as Bearer or DPoP.
44+
*
45+
* @return the authorization schemes
46+
*/
47+
Set<String> getSchemes();
48+
3849
/**
3950
* Return an authenticator for the supplied challenge.
4051
*

integration/uma/src/test/java/com/inrupt/client/integration/uma/UmaAccessGrantScenarioTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@
2424

2525
public class UmaAccessGrantScenarioTest extends AccessGrantScenarios {
2626

27-
}
27+
}

openid/src/main/java/com/inrupt/client/openid/OpenIdAuthenticationProvider.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import java.util.Optional;
3131
import java.util.Set;
32+
import java.util.TreeSet;
3233
import java.util.concurrent.CompletableFuture;
3334
import java.util.concurrent.CompletionStage;
3435

@@ -38,11 +39,15 @@
3839
public class OpenIdAuthenticationProvider implements AuthenticationProvider {
3940

4041
private static final String BEARER = "Bearer";
42+
private static final String DPOP = "DPoP";
4143

4244
private final int priorityLevel;
45+
private final Set<String> schemes = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
4346

4447
public OpenIdAuthenticationProvider() {
4548
this(50);
49+
schemes.add(BEARER);
50+
schemes.add(DPOP);
4651
}
4752

4853
/**
@@ -59,15 +64,20 @@ public String getScheme() {
5964
return BEARER;
6065
}
6166

67+
@Override
68+
public Set<String> getSchemes() {
69+
return schemes;
70+
}
71+
6272
@Override
6373
public Authenticator getAuthenticator(final Challenge challenge) {
6474
validate(challenge);
6575
return new OpenIdAuthenticator(priorityLevel);
6676
}
6777

68-
static void validate(final Challenge challenge) {
78+
void validate(final Challenge challenge) {
6979
if (challenge == null ||
70-
!BEARER.equalsIgnoreCase(challenge.getScheme())) {
80+
!schemes.contains(challenge.getScheme())) {
7181
throw new OpenIdException("Invalid challenge for OpenID authentication");
7282
}
7383
}

openid/src/main/java/com/inrupt/client/openid/OpenIdSession.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ private OpenIdSession(final String id, final DPoP dpop,
9191
// Support case-insensitive lookups
9292
final Set<String> schemeNames = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
9393
schemeNames.add("Bearer");
94+
schemeNames.add("DPoP");
9495

9596
this.schemes = Collections.unmodifiableSet(schemeNames);
9697
}

uma/src/main/java/com/inrupt/client/uma/UmaAuthenticationProvider.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.Objects;
3737
import java.util.Optional;
3838
import java.util.Set;
39+
import java.util.TreeSet;
3940
import java.util.concurrent.CompletableFuture;
4041
import java.util.concurrent.CompletionStage;
4142

@@ -65,9 +66,11 @@ public class UmaAuthenticationProvider implements AuthenticationProvider {
6566
private final int priorityLevel;
6667
private final UmaClient umaClient;
6768
private final NeedInfoHandler claimHandler;
69+
private final Set<String> supportedSchemes = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
6870

6971
public UmaAuthenticationProvider() {
7072
this(100);
73+
supportedSchemes.add(UMA);
7174
}
7275

7376
/**
@@ -92,11 +95,17 @@ public UmaAuthenticationProvider(final int priority, final UmaClient umaClient)
9295
this.claimHandler = new NeedInfoHandler();
9396
}
9497

98+
/* deprecated */
9599
@Override
96100
public String getScheme() {
97101
return UMA;
98102
}
99103

104+
@Override
105+
public Set<String> getSchemes() {
106+
return supportedSchemes;
107+
}
108+
100109
@Override
101110
public Authenticator getAuthenticator(final Challenge challenge) {
102111
validate(challenge);

0 commit comments

Comments
 (0)