Polish core format

Issue gh-8945
This commit is contained in:
Rob Winch 2020-08-24 09:48:12 -05:00
parent 254f2e2aec
commit 4fd67b48e0
19 changed files with 150 additions and 39 deletions

View File

@ -82,10 +82,13 @@ public class PrePostAdviceReactiveMethodInterceptor implements MethodInterceptor
Class<?> targetClass = invocation.getThis().getClass();
Collection<ConfigAttribute> attributes = this.attributeSource.getAttributes(method, targetClass);
PreInvocationAttribute preAttr = findPreInvocationAttribute(attributes);
// @formatter:off
Mono<Authentication> toInvoke = ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication).defaultIfEmpty(this.anonymous)
.map(SecurityContext::getAuthentication)
.defaultIfEmpty(this.anonymous)
.filter((auth) -> this.preInvocationAdvice.before(auth, invocation, preAttr))
.switchIfEmpty(Mono.defer(() -> Mono.error(new AccessDeniedException("Denied"))));
// @formatter:on
PostInvocationAttribute attr = findPostInvocationAttribute(attributes);
if (Mono.class.isAssignableFrom(returnType)) {
return toInvoke.flatMap((auth) -> PrePostAdviceReactiveMethodInterceptor.<Mono<?>>proceed(invocation)

View File

@ -91,11 +91,16 @@ public abstract class AbstractUserDetailsReactiveAuthenticationManager implement
public Mono<Authentication> authenticate(Authentication authentication) {
String username = authentication.getName();
String presentedPassword = (String) authentication.getCredentials();
return retrieveUser(username).doOnNext(this.preAuthenticationChecks::check).publishOn(this.scheduler)
// @formatter:off
return retrieveUser(username)
.doOnNext(this.preAuthenticationChecks::check)
.publishOn(this.scheduler)
.filter((userDetails) -> this.passwordEncoder.matches(presentedPassword, userDetails.getPassword()))
.switchIfEmpty(Mono.defer(() -> Mono.error(new BadCredentialsException("Invalid Credentials"))))
.flatMap((userDetails) -> upgradeEncodingIfNecessary(userDetails, presentedPassword))
.doOnNext(this.postAuthenticationChecks::check).map(this::createUsernamePasswordAuthenticationToken);
.doOnNext(this.postAuthenticationChecks::check)
.map(this::createUsernamePasswordAuthenticationToken);
// @formatter:on
}
private Mono<UserDetails> upgradeEncodingIfNecessary(UserDetails userDetails, String presentedPassword) {

View File

@ -48,7 +48,11 @@ public class DelegatingReactiveAuthenticationManager implements ReactiveAuthenti
@Override
public Mono<Authentication> authenticate(Authentication authentication) {
return Flux.fromIterable(this.delegates).concatMap((m) -> m.authenticate(authentication)).next();
// @formatter:off
return Flux.fromIterable(this.delegates)
.concatMap((m) -> m.authenticate(authentication))
.next();
// @formatter:on
}
}

View File

@ -47,8 +47,12 @@ public class ReactiveAuthenticationManagerAdapter implements ReactiveAuthenticat
@Override
public Mono<Authentication> authenticate(Authentication token) {
return Mono.just(token).publishOn(this.scheduler).flatMap(this::doAuthenticate)
// @formatter:off
return Mono.just(token)
.publishOn(this.scheduler)
.flatMap(this::doAuthenticate)
.filter(Authentication::isAuthenticated);
// @formatter:on
}
private Mono<Authentication> doAuthenticate(Authentication authentication) {

View File

@ -43,9 +43,14 @@ public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthori
@Override
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, T object) {
return authentication.filter((a) -> a.isAuthenticated()).flatMapIterable(Authentication::getAuthorities)
.map(GrantedAuthority::getAuthority).any(this.authorities::contains).map(AuthorizationDecision::new)
// @formatter:off
return authentication.filter((a) -> a.isAuthenticated())
.flatMapIterable(Authentication::getAuthorities)
.map(GrantedAuthority::getAuthority)
.any(this.authorities::contains)
.map(AuthorizationDecision::new)
.defaultIfEmpty(new AuthorizationDecision(false));
// @formatter:on
}
/**

View File

@ -47,9 +47,12 @@ public interface ReactiveAuthorizationManager<T> {
* denied
*/
default Mono<Void> verify(Mono<Authentication> authentication, T object) {
return check(authentication, object).filter(AuthorizationDecision::isGranted)
// @formatter:off
return check(authentication, object)
.filter(AuthorizationDecision::isGranted)
.switchIfEmpty(Mono.defer(() -> Mono.error(new AccessDeniedException("Access Denied"))))
.flatMap((decision) -> Mono.empty());
// @formatter:on
}
}

View File

@ -41,8 +41,11 @@ public final class ReactiveSecurityContextHolder {
* @return the {@code Mono<SecurityContext>}
*/
public static Mono<SecurityContext> getContext() {
return Mono.subscriberContext().filter(ReactiveSecurityContextHolder::hasSecurityContext)
// @formatter:off
return Mono.subscriberContext()
.filter(ReactiveSecurityContextHolder::hasSecurityContext)
.flatMap(ReactiveSecurityContextHolder::getSecurityContext);
// @formatter:on
}
private static boolean hasSecurityContext(Context context) {

View File

@ -72,15 +72,22 @@ public class MapReactiveUserDetailsService implements ReactiveUserDetailsService
@Override
public Mono<UserDetails> updatePassword(UserDetails user, String newPassword) {
return Mono.just(user).map((userDetails) -> withNewPassword(userDetails, newPassword))
// @formatter:off
return Mono.just(user)
.map((userDetails) -> withNewPassword(userDetails, newPassword))
.doOnNext((userDetails) -> {
String key = getKey(user.getUsername());
this.users.put(key, userDetails);
});
// @formatter:on
}
private UserDetails withNewPassword(UserDetails userDetails, String newPassword) {
return User.withUserDetails(userDetails).password(newPassword).build();
// @formatter:off
return User.withUserDetails(userDetails)
.password(newPassword)
.build();
// @formatter:on
}
private String getKey(String username) {

View File

@ -301,10 +301,15 @@ public class User implements UserDetails, CredentialsContainer {
}
public static UserBuilder withUserDetails(UserDetails userDetails) {
return withUsername(userDetails.getUsername()).password(userDetails.getPassword())
.accountExpired(!userDetails.isAccountNonExpired()).accountLocked(!userDetails.isAccountNonLocked())
.authorities(userDetails.getAuthorities()).credentialsExpired(!userDetails.isCredentialsNonExpired())
// @formatter:off
return withUsername(userDetails.getUsername())
.password(userDetails.getPassword())
.accountExpired(!userDetails.isAccountNonExpired())
.accountLocked(!userDetails.isAccountNonLocked())
.authorities(userDetails.getAuthorities())
.credentialsExpired(!userDetails.isCredentialsNonExpired())
.disabled(!userDetails.isEnabled());
// @formatter:on
}
private static class AuthorityComparator implements Comparator<GrantedAuthority>, Serializable {

View File

@ -25,6 +25,7 @@ import org.springframework.context.ApplicationContextException;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityMessageSource;
@ -109,15 +110,23 @@ import org.springframework.util.Assert;
*/
public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService, MessageSourceAware {
public static final String DEF_USERS_BY_USERNAME_QUERY = "select username,password,enabled " + "from users "
// @formatter:off
public static final String DEF_USERS_BY_USERNAME_QUERY = "select username,password,enabled "
+ "from users "
+ "where username = ?";
// @formatter:on
public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY = "select username,authority " + "from authorities "
// @formatter:off
public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY = "select username,authority "
+ "from authorities "
+ "where username = ?";
// @formatter:on
// @formatter:off
public static final String DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY = "select g.id, g.group_name, ga.authority "
+ "from groups g, group_members gm, group_authorities ga " + "where gm.username = ? "
+ "and g.id = ga.group_id " + "and g.id = gm.group_id";
+ "from groups g, group_members gm, group_authorities ga "
+ "where gm.username = ? " + "and g.id = ga.group_id " + "and g.id = gm.group_id";
// @formatter:on
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
@ -199,12 +208,15 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService, M
* objects. There should normally only be one matching user.
*/
protected List<UserDetails> loadUsersByUsername(String username) {
return getJdbcTemplate().query(this.usersByUsernameQuery, new String[] { username }, (rs, rowNum) -> {
// @formatter:off
RowMapper<UserDetails> mapper = (rs, rowNum) -> {
String username1 = rs.getString(1);
String password = rs.getString(2);
boolean enabled = rs.getBoolean(3);
return new User(username1, password, enabled, true, true, true, AuthorityUtils.NO_AUTHORITIES);
});
};
// @formatter:on
return getJdbcTemplate().query(this.usersByUsernameQuery, mapper, username);
}
/**

View File

@ -173,7 +173,7 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
*/
@Override
protected List<UserDetails> loadUsersByUsername(String username) {
return getJdbcTemplate().query(getUsersByUsernameQuery(), new String[] { username }, this::mapToUser);
return getJdbcTemplate().query(getUsersByUsernameQuery(), this::mapToUser, username);
}
private UserDetails mapToUser(ResultSet rs, int rowNum) throws SQLException {

View File

@ -79,7 +79,11 @@ public class ReactiveAuthenticationManagerAdapterTests {
public void authenticateWhenBadCredentialsThenError() {
given(this.delegate.authenticate(any())).willThrow(new BadCredentialsException("Failed"));
Mono<Authentication> result = this.manager.authenticate(this.authentication);
StepVerifier.create(result).expectError(BadCredentialsException.class).verify();
// @formatter:off
StepVerifier.create(result)
.expectError(BadCredentialsException.class)
.verify();
// @formatter:on
}
}

View File

@ -74,7 +74,11 @@ public class ReactiveUserDetailsServiceAuthenticationManagerTests {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(this.username,
this.password);
Mono<Authentication> authentication = this.manager.authenticate(token);
StepVerifier.create(authentication).expectError(BadCredentialsException.class).verify();
// @formatter:off
StepVerifier.create(authentication)
.expectError(BadCredentialsException.class)
.verify();
// @formatter:on
}
@Test
@ -89,7 +93,11 @@ public class ReactiveUserDetailsServiceAuthenticationManagerTests {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(this.username,
this.password + "INVALID");
Mono<Authentication> authentication = this.manager.authenticate(token);
StepVerifier.create(authentication).expectError(BadCredentialsException.class).verify();
// @formatter:off
StepVerifier.create(authentication)
.expectError(BadCredentialsException.class)
.verify();
// @formatter:on
}
@Test
@ -128,7 +136,11 @@ public class ReactiveUserDetailsServiceAuthenticationManagerTests {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(this.username,
this.password);
Mono<Authentication> authentication = this.manager.authenticate(token);
StepVerifier.create(authentication).expectError(BadCredentialsException.class).verify();
// @formatter:off
StepVerifier.create(authentication)
.expectError(BadCredentialsException.class)
.verify();
// @formatter:on
}
}

View File

@ -72,7 +72,11 @@ public class AuthenticatedReactiveAuthorizationManagerTests {
@Test
public void checkWhenErrorThenError() {
Mono<AuthorizationDecision> result = this.manager.check(Mono.error(new RuntimeException("ooops")), null);
StepVerifier.create(result).expectError().verify();
// @formatter:off
StepVerifier.create(result)
.expectError()
.verify();
// @formatter:on
}
}

View File

@ -58,7 +58,11 @@ public class AuthorityReactiveAuthorizationManagerTests {
@Test
public void checkWhenHasAuthorityAndErrorThenError() {
Mono<AuthorizationDecision> result = this.manager.check(Mono.error(new RuntimeException("ooops")), null);
StepVerifier.create(result).expectError().verify();
// @formatter:off
StepVerifier.create(result)
.expectError()
.verify();
// @formatter:on
}
@Test

View File

@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*/
public class RsaKeyConvertersTests {
// @formatter:off
private static final String PKCS8_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n"
+ "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCMk7CKSTfu3QoV\n"
+ "HoPVXxwZO+qweztd36cVWYqGOZinrOR2crWFu50AgR2CsdIH0+cqo7F4Vx7/3O8i\n"
@ -60,9 +61,12 @@ public class RsaKeyConvertersTests {
+ "OHjxffBM0hH+fySx8m53gFfr2BpaqDX5f6ZGBlly1SlsWZ4CchCVsc71nshipi7I\n"
+ "k8HL9F5/OpQdDNprJ5RMBNfkWE65Nrcsb1e6oPkCgYAxwgdiSOtNg8PjDVDmAhwT\n"
+ "Mxj0Dtwi2fAqQ76RVrrXpNp3uCOIAu4CfruIb5llcJ3uak0ZbnWri32AxSgk80y3\n"
+ "EWiRX/WEDu5znejF+5O3pI02atWWcnxifEKGGlxwkcMbQdA67MlrJLFaSnnGpNXo\n" + "yPfcul058SOqhafIZQMEKQ==\n"
+ "EWiRX/WEDu5znejF+5O3pI02atWWcnxifEKGGlxwkcMbQdA67MlrJLFaSnnGpNXo\n"
+ "yPfcul058SOqhafIZQMEKQ==\n"
+ "-----END PRIVATE KEY-----";
// @formatter:on
// @formatter:off
private static final String PKCS1_PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\n"
+ "MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw\n"
+ "33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW\n"
@ -76,13 +80,18 @@ public class RsaKeyConvertersTests {
+ "6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5\n"
+ "fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523\n"
+ "Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP\n"
+ "FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==\n" + "-----END RSA PRIVATE KEY-----";
+ "FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==\n"
+ "-----END RSA PRIVATE KEY-----";
// @formatter:on
// @formatter:off
private static final String X509_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n"
+ "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd\n"
+ "UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs\n"
+ "HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D\n" + "o2kQ+X5xK9cipRgEKwIDAQAB\n"
+ "HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D\n"
+ "o2kQ+X5xK9cipRgEKwIDAQAB\n"
+ "-----END PUBLIC KEY-----";
// @formatter:on
private static final String MALFORMED_X509_KEY = "malformed";

View File

@ -32,7 +32,10 @@ public class ReactiveSecurityContextHolderTests {
@Test
public void getContextWhenEmpty() {
Mono<SecurityContext> context = ReactiveSecurityContextHolder.getContext();
StepVerifier.create(context).verifyComplete();
// @formatter:off
StepVerifier.create(context)
.verifyComplete();
// @formatter:on
}
@Test
@ -42,17 +45,26 @@ public class ReactiveSecurityContextHolderTests {
Mono<SecurityContext> context = Mono.subscriberContext()
.flatMap((c) -> ReactiveSecurityContextHolder.getContext())
.subscriberContext(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(expectedContext)));
StepVerifier.create(context).expectNext(expectedContext).verifyComplete();
// @formatter:off
StepVerifier.create(context)
.expectNext(expectedContext)
.verifyComplete();
// @formatter:on
}
@Test
public void demo() {
Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
// @formatter:off
Mono<String> messageByUsername = ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication).map(Authentication::getName)
.map(SecurityContext::getAuthentication)
.map(Authentication::getName)
.flatMap(this::findMessageByUsername)
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(authentication));
StepVerifier.create(messageByUsername).expectNext("Hi user").verifyComplete();
StepVerifier.create(messageByUsername)
.expectNext("Hi user")
.verifyComplete();
// @formatter:on
}
private Mono<String> findMessageByUsername(String username) {
@ -63,20 +75,28 @@ public class ReactiveSecurityContextHolderTests {
public void setContextAndClearAndGetContextThenEmitsEmpty() {
SecurityContext expectedContext = new SecurityContextImpl(
new TestingAuthenticationToken("user", "password", "ROLE_USER"));
// @formatter:off
Mono<SecurityContext> context = Mono.subscriberContext()
.flatMap((c) -> ReactiveSecurityContextHolder.getContext())
.subscriberContext(ReactiveSecurityContextHolder.clearContext())
.subscriberContext(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(expectedContext)));
StepVerifier.create(context).verifyComplete();
StepVerifier.create(context)
.verifyComplete();
// @formatter:on
}
@Test
public void setAuthenticationAndGetContextThenEmitsContext() {
Authentication expectedAuthentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
// @formatter:off
Mono<Authentication> authentication = Mono.subscriberContext()
.flatMap((c) -> ReactiveSecurityContextHolder.getContext()).map(SecurityContext::getAuthentication)
.flatMap((c) -> ReactiveSecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
.subscriberContext(ReactiveSecurityContextHolder.withAuthentication(expectedAuthentication));
StepVerifier.create(authentication).expectNext(expectedAuthentication).verifyComplete();
StepVerifier.create(authentication)
.expectNext(expectedAuthentication)
.verifyComplete();
// @formatter:on
}
}

View File

@ -45,7 +45,11 @@ public class PasswordEncodedUser {
}
public static User.UserBuilder withUserDetails(UserDetails userDetails) {
return User.withUserDetails(userDetails).passwordEncoder(passwordEncoder());
// @formatter:off
return User
.withUserDetails(userDetails)
.passwordEncoder(passwordEncoder());
// @formatter:on
}
private static Function<String, String> passwordEncoder() {

View File

@ -51,8 +51,11 @@ public class SecurityJackson2ModulesTests {
@Test
public void readValueWhenNotAllowedOrMappedThenThrowsException() {
String content = "{\"@class\":\"org.springframework.security.jackson2.SecurityJackson2ModulesTests$NotAllowlisted\",\"property\":\"bar\"}";
assertThatExceptionOfType(Exception.class).isThrownBy(() -> this.mapper.readValue(content, Object.class))
// @formatter:off
assertThatExceptionOfType(Exception.class)
.isThrownBy(() -> this.mapper.readValue(content, Object.class))
.withStackTraceContaining("allowlist");
// @formatter:on
}
@Test