Remove internal Optional usage in favor of null checks

Issue gh-7155
This commit is contained in:
watsta 2019-08-26 15:27:40 +02:00 committed by Eleftheria Stein-Kousathana
parent 2c2d3b5d85
commit 2c2e8e5f24
9 changed files with 101 additions and 75 deletions

View File

@ -71,13 +71,19 @@ final class OAuth2ClientConfiguration {
@Override @Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
if (this.clientRegistrationRepository != null && this.authorizedClientRepository != null) { if (this.clientRegistrationRepository != null && this.authorizedClientRepository != null) {
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder authorizedClientProviderBuilder =
OAuth2AuthorizedClientProviderBuilder.builder() OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode() .authorizationCode()
.refreshToken() .refreshToken();
.clientCredentials(configurer ->
Optional.ofNullable(this.accessTokenResponseClient).ifPresent(configurer::accessTokenResponseClient)) if (this.accessTokenResponseClient != null) {
.build(); authorizedClientProviderBuilder.clientCredentials(configurer ->
configurer.accessTokenResponseClient(this.accessTokenResponseClient));
} else {
authorizedClientProviderBuilder.clientCredentials();
}
OAuth2AuthorizedClientProvider authorizedClientProvider = authorizedClientProviderBuilder.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager( DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
this.clientRegistrationRepository, this.authorizedClientRepository); this.clientRegistrationRepository, this.authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

View File

@ -27,7 +27,6 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -2665,10 +2664,10 @@ public class ServerHttpSecurity {
} }
protected void configure(ServerHttpSecurity http) { protected void configure(ServerHttpSecurity http) {
Optional.ofNullable(this.csrfTokenRepository).ifPresent(serverCsrfTokenRepository -> { if (this.csrfTokenRepository != null) {
this.filter.setCsrfTokenRepository(serverCsrfTokenRepository); this.filter.setCsrfTokenRepository(this.csrfTokenRepository);
http.logout().addLogoutHandler(new CsrfServerLogoutHandler(serverCsrfTokenRepository)); http.logout().addLogoutHandler(new CsrfServerLogoutHandler(this.csrfTokenRepository));
}); }
http.addFilterAt(this.filter, SecurityWebFiltersOrder.CSRF); http.addFilterAt(this.filter, SecurityWebFiltersOrder.CSRF);
} }
@ -3607,19 +3606,21 @@ public class ServerHttpSecurity {
return and(); return and();
} }
private Optional<ServerLogoutHandler> createLogoutHandler() { private ServerLogoutHandler createLogoutHandler() {
if (this.logoutHandlers.isEmpty()) { if (this.logoutHandlers.isEmpty()) {
return Optional.empty(); return null;
} else if (this.logoutHandlers.size() == 1) {
return this.logoutHandlers.get(0);
} else {
return new DelegatingServerLogoutHandler(this.logoutHandlers);
} }
else if (this.logoutHandlers.size() == 1) {
return Optional.of(this.logoutHandlers.get(0));
}
return Optional.of(new DelegatingServerLogoutHandler(this.logoutHandlers));
} }
protected void configure(ServerHttpSecurity http) { protected void configure(ServerHttpSecurity http) {
createLogoutHandler().ifPresent(this.logoutWebFilter::setLogoutHandler); ServerLogoutHandler logoutHandler = createLogoutHandler();
if (logoutHandler != null) {
this.logoutWebFilter.setLogoutHandler(logoutHandler);
}
http.addFilterAt(this.logoutWebFilter, SecurityWebFiltersOrder.LOGOUT); http.addFilterAt(this.logoutWebFilter, SecurityWebFiltersOrder.LOGOUT);
} }

View File

@ -18,7 +18,6 @@ package org.springframework.security.oauth2.client.oidc.web.logout;
import java.net.URI; import java.net.URI;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -52,25 +51,34 @@ public final class OidcClientInitiatedLogoutSuccessHandler extends SimpleUrlLogo
@Override @Override
protected String determineTargetUrl(HttpServletRequest request, protected String determineTargetUrl(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) { HttpServletResponse response, Authentication authentication) {
String targetUrl = null;
URI endSessionEndpoint;
if (authentication instanceof OAuth2AuthenticationToken && authentication.getPrincipal() instanceof OidcUser) {
endSessionEndpoint = this.endSessionEndpoint((OAuth2AuthenticationToken) authentication);
if (endSessionEndpoint != null) {
targetUrl = endpointUri(endSessionEndpoint, authentication);
}
}
if (targetUrl == null) {
targetUrl = super.determineTargetUrl(request, response);
}
return Optional.of(authentication) return targetUrl;
.filter(OAuth2AuthenticationToken.class::isInstance)
.filter(token -> authentication.getPrincipal() instanceof OidcUser)
.map(OAuth2AuthenticationToken.class::cast)
.flatMap(this::endSessionEndpoint)
.map(endSessionEndpoint -> endpointUri(endSessionEndpoint, authentication))
.orElseGet(() -> super.determineTargetUrl(request, response));
} }
private Optional<URI> endSessionEndpoint(OAuth2AuthenticationToken token) { private URI endSessionEndpoint(OAuth2AuthenticationToken token) {
String registrationId = token.getAuthorizedClientRegistrationId(); String registrationId = token.getAuthorizedClientRegistrationId();
return Optional.of( ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId);
this.clientRegistrationRepository.findByRegistrationId(registrationId))
.map(ClientRegistration::getProviderDetails) URI result = null;
.map(ClientRegistration.ProviderDetails::getConfigurationMetadata) if (clientRegistration != null) {
.map(configurationMetadata -> configurationMetadata.get("end_session_endpoint")) Object endSessionEndpoint = clientRegistration.getProviderDetails().getConfigurationMetadata().get("end_session_endpoint");
.map(Object::toString) if (endSessionEndpoint != null) {
.map(URI::create); result = URI.create(endSessionEndpoint.toString());
}
}
return result;
} }
private String endpointUri(URI endSessionEndpoint, Authentication authentication) { private String endpointUri(URI endSessionEndpoint, Authentication authentication) {

View File

@ -21,7 +21,6 @@ import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import com.nimbusds.oauth2.sdk.GrantType; import com.nimbusds.oauth2.sdk.GrantType;
import com.nimbusds.oauth2.sdk.ParseException; import com.nimbusds.oauth2.sdk.ParseException;
@ -141,8 +140,11 @@ public final class ClientRegistrations {
Map<String, Object> configuration = getConfiguration(issuer, oidc(uri), oidcRfc8414(uri), oauth(uri)); Map<String, Object> configuration = getConfiguration(issuer, oidc(uri), oidcRfc8414(uri), oauth(uri));
AuthorizationServerMetadata metadata = parse(configuration, AuthorizationServerMetadata::parse); AuthorizationServerMetadata metadata = parse(configuration, AuthorizationServerMetadata::parse);
ClientRegistration.Builder builder = withProviderConfiguration(metadata, issuer); ClientRegistration.Builder builder = withProviderConfiguration(metadata, issuer);
return Optional.ofNullable((String) configuration.get("userinfo_endpoint")) String userinfoEndpoint = (String) configuration.get("userinfo_endpoint");
.map(builder::userInfoUri).orElse(builder); if (userinfoEndpoint != null) {
builder.userInfoUri(userinfoEndpoint);
}
return builder;
} }
private static URI oidc(URI issuer) { private static URI oidc(URI issuer) {

View File

@ -16,11 +16,11 @@
package org.springframework.security.oauth2.server.resource.authentication; package org.springframework.security.oauth2.server.resource.authentication;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
@ -128,11 +128,12 @@ public final class OAuth2IntrospectionAuthenticationProvider implements Authenti
} }
private Collection<GrantedAuthority> extractAuthorities(Map<String, Object> claims) { private Collection<GrantedAuthority> extractAuthorities(Map<String, Object> claims) {
Collection<String> scopes = (Collection<String>) claims.get(SCOPE); Collection<String> scopes = (Collection<String>) claims.getOrDefault(SCOPE, Collections.emptyList());
return Optional.ofNullable(scopes).orElse(Collections.emptyList()) List<GrantedAuthority> authorities = new ArrayList<>();
.stream() for (String scope : scopes) {
.map(authority -> new SimpleGrantedAuthority("SCOPE_" + authority)) authorities.add(new SimpleGrantedAuthority("SCOPE_" + scope));
.collect(Collectors.toList()); }
return authorities;
} }
private static BearerTokenError invalidToken(String message) { private static BearerTokenError invalidToken(String message) {

View File

@ -17,11 +17,11 @@
package org.springframework.security.oauth2.server.resource.authentication; package org.springframework.security.oauth2.server.resource.authentication;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.security.oauth2.core.OAuth2TokenAttributes; import org.springframework.security.oauth2.core.OAuth2TokenAttributes;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -108,11 +108,12 @@ public class OAuth2IntrospectionReactiveAuthenticationManager implements Reactiv
} }
private Collection<GrantedAuthority> extractAuthorities(Map<String, Object> claims) { private Collection<GrantedAuthority> extractAuthorities(Map<String, Object> claims) {
Collection<String> scopes = (Collection<String>) claims.get(SCOPE); Collection<String> scopes = (Collection<String>) claims.getOrDefault(SCOPE, Collections.emptyList());
return Optional.ofNullable(scopes).orElse(Collections.emptyList()) List<GrantedAuthority> authorities = new ArrayList<>();
.stream() for (String scope : scopes) {
.map(authority -> new SimpleGrantedAuthority("SCOPE_" + authority)) authorities.add(new SimpleGrantedAuthority("SCOPE_" + scope));
.collect(Collectors.toList()); }
return authorities;
} }
private static BearerTokenError invalidToken(String message) { private static BearerTokenError invalidToken(String message) {

View File

@ -22,7 +22,6 @@ import java.time.Instant;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.nimbusds.oauth2.sdk.TokenIntrospectionResponse; import com.nimbusds.oauth2.sdk.TokenIntrospectionResponse;
@ -124,16 +123,22 @@ public class NimbusOpaqueTokenIntrospector implements OpaqueTokenIntrospector {
*/ */
@Override @Override
public Map<String, Object> introspect(String token) { public Map<String, Object> introspect(String token) {
TokenIntrospectionSuccessResponse response = Optional.of(token) RequestEntity<?> requestEntity = this.requestEntityConverter.convert(token);
.map(this.requestEntityConverter::convert) if (requestEntity == null) {
.map(this::makeRequest) throw new OAuth2IntrospectionException("Provided token [" + token + "] isn't active");
.map(this::adaptToNimbusResponse) }
.map(this::parseNimbusResponse)
.map(this::castToNimbusSuccess) ResponseEntity<String> responseEntity = makeRequest(requestEntity);
// relying solely on the authorization server to validate this token (not checking 'exp', for example) HTTPResponse httpResponse = adaptToNimbusResponse(responseEntity);
.filter(TokenIntrospectionSuccessResponse::isActive) TokenIntrospectionResponse introspectionResponse = parseNimbusResponse(httpResponse);
.orElseThrow(() -> new OAuth2IntrospectionException("Provided token [" + token + "] isn't active")); TokenIntrospectionSuccessResponse introspectionSuccessResponse = castToNimbusSuccess(introspectionResponse);
return convertClaimsSet(response);
// relying solely on the authorization server to validate this token (not checking 'exp', for example)
if (!introspectionSuccessResponse.isActive()) {
throw new OAuth2IntrospectionException("Provided token [" + token + "] isn't active");
}
return convertClaimsSet(introspectionSuccessResponse);
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,6 @@
package org.springframework.security.web.server.csrf; package org.springframework.security.web.server.csrf;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.springframework.http.HttpCookie; import org.springframework.http.HttpCookie;
@ -69,14 +68,17 @@ public final class CookieServerCsrfTokenRepository implements ServerCsrfTokenRep
@Override @Override
public Mono<Void> saveToken(ServerWebExchange exchange, CsrfToken token) { public Mono<Void> saveToken(ServerWebExchange exchange, CsrfToken token) {
return Mono.fromRunnable(() -> { return Mono.fromRunnable(() -> {
Optional<String> tokenValue = Optional.ofNullable(token).map(CsrfToken::getToken); String tokenValue = token != null ? token.getToken() : "";
int maxAge = !tokenValue.isEmpty() ? -1 : 0;
String path = this.cookiePath != null ? this.cookiePath : getRequestContext(exchange.getRequest());
boolean secure = exchange.getRequest().getSslInfo() != null;
ResponseCookie cookie = ResponseCookie.from(this.cookieName, tokenValue.orElse("")) ResponseCookie cookie = ResponseCookie.from(this.cookieName, tokenValue)
.domain(this.cookieDomain) .domain(this.cookieDomain)
.httpOnly(this.cookieHttpOnly) .httpOnly(this.cookieHttpOnly)
.maxAge(tokenValue.map(val -> -1).orElse(0)) .maxAge(maxAge)
.path(Optional.ofNullable(this.cookiePath).orElseGet(() -> getRequestContext(exchange.getRequest()))) .path(path)
.secure(Optional.ofNullable(exchange.getRequest().getSslInfo()).map(sslInfo -> true).orElse(false)) .secure(secure)
.build(); .build();
exchange.getResponse().addCookie(cookie); exchange.getResponse().addCookie(cookie);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +17,6 @@
package org.springframework.security.web.server.transport; package org.springframework.security.web.server.transport;
import java.net.URI; import java.net.URI;
import java.util.Optional;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -102,10 +101,11 @@ public final class HttpsRedirectWebFilter implements WebFilter {
UriComponentsBuilder.fromUri(exchange.getRequest().getURI()); UriComponentsBuilder.fromUri(exchange.getRequest().getURI());
if (port > 0) { if (port > 0) {
Optional.ofNullable(this.portMapper.lookupHttpsPort(port)) Integer httpsPort = this.portMapper.lookupHttpsPort(port);
.map(builder::port) if (httpsPort == null) {
.orElseThrow(() -> new IllegalStateException( throw new IllegalStateException("HTTP Port '" + port + "' does not have a corresponding HTTPS Port");
"HTTP Port '" + port + "' does not have a corresponding HTTPS Port")); }
builder.port(httpsPort);
} }
return builder.scheme("https").build().toUri(); return builder.scheme("https").build().toUri();