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));
|
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.
|
* Require a specific authority.
|
||||||
* @param authority the authority to require (i.e. "USER" woudl require authority of "USER").
|
* @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));
|
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
|
* Require an authenticated user
|
||||||
* @return the {@link AuthorizeExchangeSpec} to configure
|
* @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");
|
* 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.
|
||||||
|
@ -20,6 +20,10 @@ import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import reactor.core.publisher.Mono;
|
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
|
* A {@link ReactiveAuthorizationManager} that determines if the current user is
|
||||||
* authorized by evaluating if the {@link Authentication} contains a specified authority.
|
* 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
|
* @param <T> the type of object being authorized
|
||||||
*/
|
*/
|
||||||
public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthorizationManager<T> {
|
public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthorizationManager<T> {
|
||||||
private final String authority;
|
private final List<String> authorities;
|
||||||
|
|
||||||
private AuthorityReactiveAuthorizationManager(String authority) {
|
private AuthorityReactiveAuthorizationManager(String... authorities) {
|
||||||
this.authority = authority;
|
this.authorities = Arrays.asList(authorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -40,8 +44,8 @@ public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthori
|
||||||
return authentication
|
return authentication
|
||||||
.filter(a -> a.isAuthenticated())
|
.filter(a -> a.isAuthenticated())
|
||||||
.flatMapIterable( a -> a.getAuthorities())
|
.flatMapIterable( a -> a.getAuthorities())
|
||||||
.map( g-> g.getAuthority())
|
.map(g -> g.getAuthority())
|
||||||
.hasElement(this.authority)
|
.any(a -> this.authorities.contains(a))
|
||||||
.map( hasAuthority -> new AuthorizationDecision(hasAuthority))
|
.map( hasAuthority -> new AuthorizationDecision(hasAuthority))
|
||||||
.defaultIfEmpty(new AuthorizationDecision(false));
|
.defaultIfEmpty(new AuthorizationDecision(false));
|
||||||
}
|
}
|
||||||
|
@ -59,6 +63,24 @@ public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthori
|
||||||
return new AuthorityReactiveAuthorizationManager<>(authority);
|
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
|
* Creates an instance of {@link AuthorityReactiveAuthorizationManager} with the
|
||||||
* provided authority.
|
* provided authority.
|
||||||
|
@ -71,4 +93,25 @@ public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthori
|
||||||
Assert.notNull(role, "role cannot be null");
|
Assert.notNull(role, "role cannot be null");
|
||||||
return hasAuthority("ROLE_" + role);
|
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
|
@Test
|
||||||
public void checkWhenHasRoleAndNotAuthorizedThenReturnTrue() {
|
public void checkWhenHasRoleAndNotAuthorizedThenReturnFalse() {
|
||||||
manager = AuthorityReactiveAuthorizationManager.hasRole("ADMIN");
|
manager = AuthorityReactiveAuthorizationManager.hasRole("ADMIN");
|
||||||
authentication = new TestingAuthenticationToken("rob", "secret", "ADMIN");
|
authentication = new TestingAuthenticationToken("rob", "secret", "ADMIN");
|
||||||
|
|
||||||
|
@ -114,6 +114,26 @@ public class AuthorityReactiveAuthorizationManagerTests {
|
||||||
assertThat(granted).isFalse();
|
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)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void hasRoleWhenNullThenException() {
|
public void hasRoleWhenNullThenException() {
|
||||||
String role = null;
|
String role = null;
|
||||||
|
@ -125,4 +145,30 @@ public class AuthorityReactiveAuthorizationManagerTests {
|
||||||
String authority = null;
|
String authority = null;
|
||||||
AuthorityReactiveAuthorizationManager.hasAuthority(authority);
|
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