Replace Streams with Loops

First version of replacing streams

fix wwwAuthenticate and codestyle

fix errors in implementation to pass tests

Fix review notes

Remove uneccessary final to align with cb

Short circuit way to authorize

Simplify error message, make code readably

Return error while duplicate key found

Delete check for duplicate, checkstyle issues

Return duplicate error

Fixes gh-7154
This commit is contained in:
kostya05983
2019-08-04 17:11:24 +07:00
committed by Josh Cummings
parent d6d0d89ff8
commit f6c650db47
30 changed files with 283 additions and 184 deletions

View File

@@ -22,7 +22,7 @@ import java.time.Instant;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.ArrayList;
import com.nimbusds.oauth2.sdk.TokenIntrospectionResponse;
import com.nimbusds.oauth2.sdk.TokenIntrospectionSuccessResponse;
@@ -192,9 +192,11 @@ public class NimbusOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
private Map<String, Object> convertClaimsSet(TokenIntrospectionSuccessResponse response) {
Map<String, Object> claims = response.toJSONObject();
if (response.getAudience() != null) {
List<String> audience = response.getAudience().stream()
.map(Audience::getValue).collect(Collectors.toList());
claims.put(AUDIENCE, Collections.unmodifiableList(audience));
List<String> audiences = new ArrayList<>();
for (Audience audience : response.getAudience()) {
audiences.add(audience.getValue());
}
claims.put(AUDIENCE, Collections.unmodifiableList(audiences));
}
if (response.getClientID() != null) {
claims.put(CLIENT_ID, response.getClientID().getValue());

View File

@@ -22,7 +22,7 @@ import java.time.Instant;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.ArrayList;
import com.nimbusds.oauth2.sdk.TokenIntrospectionResponse;
import com.nimbusds.oauth2.sdk.TokenIntrospectionSuccessResponse;
@@ -153,9 +153,11 @@ public class NimbusReactiveOpaqueTokenIntrospector implements ReactiveOpaqueToke
private Map<String, Object> convertClaimsSet(TokenIntrospectionSuccessResponse response) {
Map<String, Object> claims = response.toJSONObject();
if (response.getAudience() != null) {
List<String> audience = response.getAudience().stream()
.map(Audience::getValue).collect(Collectors.toList());
claims.put(AUDIENCE, Collections.unmodifiableList(audience));
List<String> audiences = new ArrayList<>();
for (Audience audience : response.getAudience()) {
audiences.add(audience.getValue());
}
claims.put(AUDIENCE, Collections.unmodifiableList(audiences));
}
if (response.getClientID() != null) {
claims.put(CLIENT_ID, response.getClientID().getValue());

View File

@@ -19,7 +19,6 @@ package org.springframework.security.oauth2.server.resource.web;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -41,10 +40,10 @@ import org.springframework.util.StringUtils;
* {@code WWW-Authenticate} HTTP header.
*
* @author Vedran Pavic
* @since 5.1
* @see BearerTokenError
* @see <a href="https://tools.ietf.org/html/rfc6750#section-3" target="_blank">RFC 6750 Section 3: The WWW-Authenticate
* Response Header Field</a>
* @since 5.1
*/
public final class BearerTokenAuthenticationEntryPoint implements AuthenticationEntryPoint {
@@ -54,8 +53,8 @@ public final class BearerTokenAuthenticationEntryPoint implements Authentication
* Collect error details from the provided parameters and format according to
* RFC 6750, specifically {@code error}, {@code error_description}, {@code error_uri}, and {@code scope}.
*
* @param request that resulted in an <code>AuthenticationException</code>
* @param response so that the user agent can begin authentication
* @param request that resulted in an <code>AuthenticationException</code>
* @param response so that the user agent can begin authentication
* @param authException that caused the invocation
*/
@Override
@@ -112,13 +111,22 @@ public final class BearerTokenAuthenticationEntryPoint implements Authentication
}
private static String computeWWWAuthenticateHeaderValue(Map<String, String> parameters) {
String wwwAuthenticate = "Bearer";
StringBuilder wwwAuthenticate = new StringBuilder();
wwwAuthenticate.append("Bearer");
if (!parameters.isEmpty()) {
wwwAuthenticate += parameters.entrySet().stream()
.map(attribute -> attribute.getKey() + "=\"" + attribute.getValue() + "\"")
.collect(Collectors.joining(", ", " ", ""));
wwwAuthenticate.append(" ");
int i = 0;
for (Map.Entry<String, String> entry : parameters.entrySet()) {
wwwAuthenticate.append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
if (i != parameters.size() - 1) {
wwwAuthenticate.append(", ");
}
i++;
}
}
return wwwAuthenticate;
return wwwAuthenticate.toString();
}
}

View File

@@ -30,12 +30,11 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Translates any {@link AccessDeniedException} into an HTTP response in accordance with
* <a href="https://tools.ietf.org/html/rfc6750#section-3" target="_blank">RFC 6750 Section 3: The WWW-Authenticate</a>.
*
* <p>
* So long as the class can prove that the request has a valid OAuth 2.0 {@link Authentication}, then will return an
* <a href="https://tools.ietf.org/html/rfc6750#section-3.1" target="_blank">insufficient scope error</a>; otherwise,
* it will simply indicate the scheme (Bearer) and any configured realm.
@@ -51,10 +50,9 @@ public final class BearerTokenAccessDeniedHandler implements AccessDeniedHandler
* Collect error details from the provided parameters and format according to
* RFC 6750, specifically {@code error}, {@code error_description}, {@code error_uri}, and {@code scope}.
*
* @param request that resulted in an <code>AccessDeniedException</code>
* @param response so that the user agent can be advised of the failure
* @param request that resulted in an <code>AccessDeniedException</code>
* @param response so that the user agent can be advised of the failure
* @param accessDeniedException that caused the invocation
*
*/
@Override
public void handle(
@@ -90,13 +88,22 @@ public final class BearerTokenAccessDeniedHandler implements AccessDeniedHandler
}
private static String computeWWWAuthenticateHeaderValue(Map<String, String> parameters) {
String wwwAuthenticate = "Bearer";
StringBuilder wwwAuthenticate = new StringBuilder();
wwwAuthenticate.append("Bearer");
if (!parameters.isEmpty()) {
wwwAuthenticate += parameters.entrySet().stream()
.map(attribute -> attribute.getKey() + "=\"" + attribute.getValue() + "\"")
.collect(Collectors.joining(", ", " ", ""));
wwwAuthenticate.append(" ");
int i = 0;
for (Map.Entry<String, String> entry : parameters.entrySet()) {
wwwAuthenticate.append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
if (i != parameters.size() - 1) {
wwwAuthenticate.append(", ");
}
i++;
}
}
return wwwAuthenticate;
return wwwAuthenticate.toString();
}
}

View File

@@ -30,7 +30,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Translates any {@link AccessDeniedException} into an HTTP response in accordance with
@@ -91,13 +90,20 @@ public class BearerTokenServerAccessDeniedHandler implements ServerAccessDeniedH
}
private static String computeWWWAuthenticateHeaderValue(Map<String, String> parameters) {
String wwwAuthenticate = "Bearer";
StringBuilder wwwAuthenticate = new StringBuilder();
wwwAuthenticate.append("Bearer");
if (!parameters.isEmpty()) {
wwwAuthenticate += parameters.entrySet().stream()
.map(attribute -> attribute.getKey() + "=\"" + attribute.getValue() + "\"")
.collect(Collectors.joining(", ", " ", ""));
wwwAuthenticate.append(" ");
int i = 0;
for (Map.Entry<String, String> entry : parameters.entrySet()) {
wwwAuthenticate.append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
if (i != parameters.size() - 1) {
wwwAuthenticate.append(", ");
}
i++;
}
}
return wwwAuthenticate;
return wwwAuthenticate.toString();
}
}

View File

@@ -32,7 +32,6 @@ import reactor.core.publisher.Mono;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* An {@link AuthenticationEntryPoint} implementation used to commence authentication of protected resource requests
@@ -42,10 +41,10 @@ import java.util.stream.Collectors;
* {@code WWW-Authenticate} HTTP header.
*
* @author Rob Winch
* @since 5.1
* @see BearerTokenError
* @see <a href="https://tools.ietf.org/html/rfc6750#section-3" target="_blank">RFC 6750 Section 3: The WWW-Authenticate
* Response Header Field</a>
* @since 5.1
*/
public final class BearerTokenServerAuthenticationEntryPoint implements
ServerAuthenticationEntryPoint {
@@ -111,13 +110,21 @@ public final class BearerTokenServerAuthenticationEntryPoint implements
}
private static String computeWWWAuthenticateHeaderValue(Map<String, String> parameters) {
String wwwAuthenticate = "Bearer";
StringBuilder wwwAuthenticate = new StringBuilder();
wwwAuthenticate.append("Bearer");
if (!parameters.isEmpty()) {
wwwAuthenticate += parameters.entrySet().stream()
.map(attribute -> attribute.getKey() + "=\"" + attribute.getValue() + "\"")
.collect(Collectors.joining(", ", " ", ""));
wwwAuthenticate.append(" ");
int i = 0;
for (Map.Entry<String, String> entry : parameters.entrySet()) {
wwwAuthenticate.append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
if (i != parameters.size() - 1) {
wwwAuthenticate.append(", ");
}
i++;
}
}
return wwwAuthenticate;
return wwwAuthenticate.toString();
}
}