Add hasAnyAuthority() and hasAnyRole() in AuthorizeExchangeSpec
Fixes gh-6306
This commit is contained in:
parent
a919b4e916
commit
e60ae4984a
|
@ -1563,6 +1563,15 @@ public class ServerHttpSecurity {
|
|||
return access(AuthorityReactiveAuthorizationManager.hasRole(role));
|
||||
}
|
||||
|
||||
/**
|
||||
* Require any specific role. This is a shortcut for {@link #hasAnyAuthority(String...)}
|
||||
* @param roles the roles (i.e. "USER" would require "ROLE_USER")
|
||||
* @return the {@link AuthorizeExchangeSpec} to configure
|
||||
*/
|
||||
public AuthorizeExchangeSpec hasAnyRole(String... roles) {
|
||||
return access(AuthorityReactiveAuthorizationManager.hasAnyRole(roles));
|
||||
}
|
||||
|
||||
/**
|
||||
* Require a specific authority.
|
||||
* @param authority the authority to require (i.e. "USER" woudl require authority of "USER").
|
||||
|
@ -1572,6 +1581,15 @@ public class ServerHttpSecurity {
|
|||
return access(AuthorityReactiveAuthorizationManager.hasAuthority(authority));
|
||||
}
|
||||
|
||||
/**
|
||||
* Require any authority
|
||||
* @param authorities the authorities to require (i.e. "USER" would require authority of "USER").
|
||||
* @return the {@link AuthorizeExchangeSpec} to configure
|
||||
*/
|
||||
public AuthorizeExchangeSpec hasAnyAuthority(String... authorities) {
|
||||
return access(AuthorityReactiveAuthorizationManager.hasAnyAuthority(authorities));
|
||||
}
|
||||
|
||||
/**
|
||||
* Require an authenticated user
|
||||
* @return the {@link AuthorizeExchangeSpec} to configure
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,6 +20,10 @@ import org.springframework.security.core.Authentication;
|
|||
import org.springframework.util.Assert;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A {@link ReactiveAuthorizationManager} that determines if the current user is
|
||||
* authorized by evaluating if the {@link Authentication} contains a specified authority.
|
||||
|
@ -29,10 +33,10 @@ import reactor.core.publisher.Mono;
|
|||
* @param <T> the type of object being authorized
|
||||
*/
|
||||
public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthorizationManager<T> {
|
||||
private final String authority;
|
||||
private final List<String> authorities;
|
||||
|
||||
private AuthorityReactiveAuthorizationManager(String authority) {
|
||||
this.authority = authority;
|
||||
private AuthorityReactiveAuthorizationManager(String... authorities) {
|
||||
this.authorities = Arrays.asList(authorities);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,8 +44,8 @@ public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthori
|
|||
return authentication
|
||||
.filter(a -> a.isAuthenticated())
|
||||
.flatMapIterable( a -> a.getAuthorities())
|
||||
.map( g-> g.getAuthority())
|
||||
.hasElement(this.authority)
|
||||
.map(g -> g.getAuthority())
|
||||
.any(a -> this.authorities.contains(a))
|
||||
.map( hasAuthority -> new AuthorizationDecision(hasAuthority))
|
||||
.defaultIfEmpty(new AuthorizationDecision(false));
|
||||
}
|
||||
|
@ -59,6 +63,24 @@ public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthori
|
|||
return new AuthorityReactiveAuthorizationManager<>(authority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link AuthorityReactiveAuthorizationManager} with the
|
||||
* provided authorities.
|
||||
*
|
||||
* @author Robbie Martinus
|
||||
* @param authorities the authorities to check for
|
||||
* @param <T> the type of object being authorized
|
||||
* @return the new instance
|
||||
*/
|
||||
public static <T> AuthorityReactiveAuthorizationManager<T> hasAnyAuthority(String... authorities) {
|
||||
Assert.notNull(authorities, "authorities cannot be null");
|
||||
for (String authority : authorities) {
|
||||
Assert.notNull(authority, "authority cannot be null");
|
||||
}
|
||||
|
||||
return new AuthorityReactiveAuthorizationManager<>(authorities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link AuthorityReactiveAuthorizationManager} with the
|
||||
* provided authority.
|
||||
|
@ -71,4 +93,25 @@ public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthori
|
|||
Assert.notNull(role, "role cannot be null");
|
||||
return hasAuthority("ROLE_" + role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link AuthorityReactiveAuthorizationManager} with the
|
||||
* provided authorities.
|
||||
*
|
||||
* @author Robbie Martinus
|
||||
* @param roles the authorities to check for prefixed with "ROLE_"
|
||||
* @param <T> the type of object being authorized
|
||||
* @return the new instance
|
||||
*/
|
||||
public static <T> AuthorityReactiveAuthorizationManager<T> hasAnyRole(String... roles) {
|
||||
Assert.notNull(roles, "roles cannot be null");
|
||||
for (String role : roles) {
|
||||
Assert.notNull(role, "role cannot be null");
|
||||
}
|
||||
|
||||
return hasAnyAuthority(Stream.of(roles)
|
||||
.map(r -> "ROLE_" + r)
|
||||
.toArray(String[]::new)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ public class AuthorityReactiveAuthorizationManagerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void checkWhenHasRoleAndNotAuthorizedThenReturnTrue() {
|
||||
public void checkWhenHasRoleAndNotAuthorizedThenReturnFalse() {
|
||||
manager = AuthorityReactiveAuthorizationManager.hasRole("ADMIN");
|
||||
authentication = new TestingAuthenticationToken("rob", "secret", "ADMIN");
|
||||
|
||||
|
@ -114,6 +114,26 @@ public class AuthorityReactiveAuthorizationManagerTests {
|
|||
assertThat(granted).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkWhenHasAnyRoleAndAuthorizedThenReturnTrue() {
|
||||
manager = AuthorityReactiveAuthorizationManager.hasAnyRole("GENERAL", "USER", "TEST");
|
||||
authentication = new TestingAuthenticationToken("rob", "secret", "ROLE_USER", "ROLE_AUDITING", "ROLE_ADMIN");
|
||||
|
||||
boolean granted = manager.check(Mono.just(authentication), null).block().isGranted();
|
||||
|
||||
assertThat(granted).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkWhenHasAnyRoleAndNotAuthorizedThenReturnFalse() {
|
||||
manager = AuthorityReactiveAuthorizationManager.hasAnyRole("GENERAL", "USER", "TEST");
|
||||
authentication = new TestingAuthenticationToken("rob", "secret", "USER", "AUDITING", "ADMIN");
|
||||
|
||||
boolean granted = manager.check(Mono.just(authentication), null).block().isGranted();
|
||||
|
||||
assertThat(granted).isFalse();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void hasRoleWhenNullThenException() {
|
||||
String role = null;
|
||||
|
@ -125,4 +145,30 @@ public class AuthorityReactiveAuthorizationManagerTests {
|
|||
String authority = null;
|
||||
AuthorityReactiveAuthorizationManager.hasAuthority(authority);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void hasAnyRoleWhenNullThenException() {
|
||||
String role = null;
|
||||
AuthorityReactiveAuthorizationManager.hasAnyRole(role);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void hasAnyAuthorityWhenNullThenException() {
|
||||
String authority = null;
|
||||
AuthorityReactiveAuthorizationManager.hasAnyAuthority(authority);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void hasAnyRoleWhenOneIsNullThenException() {
|
||||
String role1 = "ROLE_ADMIN";
|
||||
String role2 = null;
|
||||
AuthorityReactiveAuthorizationManager.hasAnyRole(role1, role2);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void hasAnyAuthorityWhenOneIsNullThenException() {
|
||||
String authority1 = "ADMIN";
|
||||
String authority2 = null;
|
||||
AuthorityReactiveAuthorizationManager.hasAnyAuthority(authority1, authority2);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue