mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-10-22 10:18:53 +00:00
Make withRoles Check Only Roles
This commit clarifies the semantics of withRoles, which is to check the role-based authorities in an authentication. Closes gh-17843
This commit is contained in:
parent
bd119ac411
commit
de10e08348
@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.authentication.ldap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.directory.SearchControls;
|
||||
@ -39,7 +38,6 @@ import org.springframework.security.config.annotation.configuration.ObjectPostPr
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
|
||||
@ -120,8 +118,7 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
|
||||
this.spring.register(BindAuthenticationConfig.class).autowire();
|
||||
|
||||
this.mockMvc.perform(formLogin().user("bob").password("bobspassword"))
|
||||
.andExpect(authenticated().withUsername("bob")
|
||||
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
|
||||
.andExpect(authenticated().withUsername("bob").withRoles("DEVELOPERS"));
|
||||
}
|
||||
|
||||
// SEC-2472
|
||||
@ -130,8 +127,7 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
|
||||
this.spring.register(PasswordEncoderConfig.class).autowire();
|
||||
|
||||
this.mockMvc.perform(formLogin().user("bcrypt").password("password"))
|
||||
.andExpect(authenticated().withUsername("bcrypt")
|
||||
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
|
||||
.andExpect(authenticated().withUsername("bcrypt").withRoles("DEVELOPERS"));
|
||||
}
|
||||
|
||||
private LdapAuthenticationProvider ldapProvider() {
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.security.config.annotation.authentication.ldap;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
@ -28,8 +26,6 @@ import org.springframework.security.config.annotation.authentication.ldap.LdapAu
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders;
|
||||
import org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
@ -64,7 +60,7 @@ public class LdapAuthenticationProviderConfigurerTests {
|
||||
.password("bobspassword");
|
||||
SecurityMockMvcResultMatchers.AuthenticatedMatcher expectedUser = authenticated()
|
||||
.withUsername("bob")
|
||||
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS")));
|
||||
.withRoles("DEVELOPERS");
|
||||
// @formatter:on
|
||||
this.mockMvc.perform(request).andExpect(expectedUser);
|
||||
}
|
||||
@ -79,7 +75,7 @@ public class LdapAuthenticationProviderConfigurerTests {
|
||||
.password("bobspassword");
|
||||
SecurityMockMvcResultMatchers.AuthenticatedMatcher expectedUser = authenticated()
|
||||
.withUsername("bob")
|
||||
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROL_DEVELOPERS")));
|
||||
.withRoles("ROL_", new String[] { "DEVELOPERS" });
|
||||
// @formatter:on
|
||||
this.mockMvc.perform(request).andExpect(expectedUser);
|
||||
}
|
||||
@ -108,8 +104,7 @@ public class LdapAuthenticationProviderConfigurerTests {
|
||||
.password("otherbenspassword");
|
||||
SecurityMockMvcResultMatchers.AuthenticatedMatcher expectedUser = authenticated()
|
||||
.withUsername("otherben")
|
||||
.withAuthorities(
|
||||
AuthorityUtils.createAuthorityList("ROLE_SUBMANAGERS", "ROLE_MANAGERS", "ROLE_DEVELOPERS"));
|
||||
.withRoles("SUBMANAGERS", "MANAGERS", "DEVELOPERS");
|
||||
// @formatter:on
|
||||
this.mockMvc.perform(request).andExpect(expectedUser);
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.security.config.annotation.authentication.ldap;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@ -34,7 +33,6 @@ import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
|
||||
import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator;
|
||||
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders;
|
||||
@ -79,7 +77,7 @@ public class NamespaceLdapAuthenticationProviderTests {
|
||||
.user("bob")
|
||||
.password("bobspassword");
|
||||
SecurityMockMvcResultMatchers.AuthenticatedMatcher user = authenticated()
|
||||
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("PREFIX_DEVELOPERS")));
|
||||
.withRoles("PREFIX_", new String[] { "DEVELOPERS" });
|
||||
// @formatter:on
|
||||
this.mockMvc.perform(request).andExpect(user);
|
||||
}
|
||||
@ -103,7 +101,7 @@ public class NamespaceLdapAuthenticationProviderTests {
|
||||
.user("bob")
|
||||
.password("bobspassword");
|
||||
SecurityMockMvcResultMatchers.AuthenticatedMatcher user = authenticated()
|
||||
.withAuthorities(Collections.singleton(new SimpleGrantedAuthority("ROLE_EXTRA")));
|
||||
.withRoles("EXTRA");
|
||||
// @formatter:on
|
||||
this.mockMvc.perform(request).andExpect(user);
|
||||
}
|
||||
|
@ -18,7 +18,9 @@ package org.springframework.security.test.web.servlet.response;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jspecify.annotations.NullUnmarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
@ -94,6 +96,8 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
private @Nullable Collection<? extends GrantedAuthority> expectedGrantedAuthorities;
|
||||
|
||||
private Predicate<GrantedAuthority> ignoreAuthorities = (authority) -> false;
|
||||
|
||||
private @Nullable Consumer<Authentication> assertAuthentication;
|
||||
|
||||
AuthenticatedMatcher() {
|
||||
@ -132,7 +136,8 @@ public final class SecurityMockMvcResultMatchers {
|
||||
}
|
||||
if (this.expectedGrantedAuthorities != null) {
|
||||
AssertionErrors.assertTrue("Authentication cannot be null", auth != null);
|
||||
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
|
||||
Collection<? extends GrantedAuthority> authorities = new ArrayList<>(auth.getAuthorities());
|
||||
authorities.removeIf(this.ignoreAuthorities);
|
||||
AssertionErrors.assertTrue(
|
||||
authorities + " does not contain the same authorities as " + this.expectedGrantedAuthorities,
|
||||
authorities.containsAll(this.expectedGrantedAuthorities));
|
||||
@ -212,16 +217,43 @@ public final class SecurityMockMvcResultMatchers {
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the {@link Authentication#getAuthorities()}
|
||||
* Specifies the expected roles.
|
||||
* <p>
|
||||
* Since a set of authorities can contain more than just roles, this method
|
||||
* differs from {@link #withAuthorities} in that it only verifies the authorities
|
||||
* prefixed by {@code ROLE_}. Other authorities are ignored.
|
||||
* <p>
|
||||
* If you want to validate more than just roles, please use
|
||||
* {@link #withAuthorities}.
|
||||
* @param roles the roles. Each value is automatically prefixed with "ROLE_"
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
public AuthenticatedMatcher withRoles(String... roles) {
|
||||
Collection<GrantedAuthority> authorities = new ArrayList<>();
|
||||
return withRoles("ROLE_", roles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the expected roles.
|
||||
* <p>
|
||||
* Since a set of authorities can contain more than just roles, this method
|
||||
* differs from {@link #withAuthorities} in that it only verifies the authorities
|
||||
* prefixed by {@code ROLE_}. Other authorities are ignored.
|
||||
* <p>
|
||||
* If you want to validate more than just roles, please use
|
||||
* {@link #withAuthorities}.
|
||||
* @param rolePrefix the role prefix
|
||||
* @param roles the roles. Each value is automatically prefixed with the
|
||||
* {@code rolePrefix}
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
* @since 7.0
|
||||
*/
|
||||
public AuthenticatedMatcher withRoles(String rolePrefix, String[] roles) {
|
||||
List<GrantedAuthority> withPrefix = new ArrayList<>();
|
||||
for (String role : roles) {
|
||||
authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
|
||||
withPrefix.add(new SimpleGrantedAuthority(rolePrefix + role));
|
||||
}
|
||||
return withAuthorities(authorities);
|
||||
this.ignoreAuthorities = (authority) -> !authority.getAuthority().startsWith(rolePrefix);
|
||||
return withAuthorities(withPrefix);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user