SecurityMockMvcResultMatchers.withAuthorities(String...)
CodeQL Advanced / codeql-analysis-call (push) Waiting to run
Details
CI / Build (17, ubuntu-latest) (push) Waiting to run
Details
CI / Build (17, windows-latest) (push) Waiting to run
Details
CI / Deploy Artifacts (push) Blocked by required conditions
Details
CI / Deploy Docs (push) Blocked by required conditions
Details
CI / Deploy Schema (push) Blocked by required conditions
Details
CI / Perform Release (push) Blocked by required conditions
Details
CI / Send Notification (push) Blocked by required conditions
Details
Deploy Docs / build (push) Waiting to run
Details
CodeQL Advanced / codeql-analysis-call (push) Waiting to run
Details
CI / Build (17, ubuntu-latest) (push) Waiting to run
Details
CI / Build (17, windows-latest) (push) Waiting to run
Details
CI / Deploy Artifacts (push) Blocked by required conditions
Details
CI / Deploy Docs (push) Blocked by required conditions
Details
CI / Deploy Schema (push) Blocked by required conditions
Details
CI / Perform Release (push) Blocked by required conditions
Details
CI / Send Notification (push) Blocked by required conditions
Details
Deploy Docs / build (push) Waiting to run
Details
Closes gh-17974
This commit is contained in:
parent
0e99324c43
commit
7f10897de3
|
@ -70,6 +70,10 @@ http.csrf((csrf) -> csrf.spa());
|
|||
* Made so that SLO still returns `<saml2:LogoutResponse>` even when validation fails
|
||||
* Removed Open SAML 4 support; applications should migrate to Open SAML 5
|
||||
|
||||
== Test
|
||||
|
||||
* https://github.com/spring-projects/spring-security/issues/17974[Add SecurityMockMvcResultMatchers.withAuthorities(String...)]
|
||||
|
||||
== Web
|
||||
|
||||
* Removed `MvcRequestMatcher` and `AntPathRequestMatcher` in favor of `PathPatternRequestMatcher`
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.security.test.web.servlet.response;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -38,6 +39,7 @@ import org.springframework.test.util.AssertionErrors;
|
|||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Security related {@link MockMvc} {@link ResultMatcher}s.
|
||||
|
@ -96,6 +98,8 @@ public final class SecurityMockMvcResultMatchers {
|
|||
|
||||
private @Nullable Collection<? extends GrantedAuthority> expectedGrantedAuthorities;
|
||||
|
||||
private @Nullable Collection<String> expectedAuthorities;
|
||||
|
||||
private Predicate<GrantedAuthority> ignoreAuthorities = (authority) -> false;
|
||||
|
||||
private @Nullable Consumer<Authentication> assertAuthentication;
|
||||
|
@ -145,6 +149,20 @@ public final class SecurityMockMvcResultMatchers {
|
|||
this.expectedGrantedAuthorities + " does not contain the same authorities as " + authorities,
|
||||
this.expectedGrantedAuthorities.containsAll(authorities));
|
||||
}
|
||||
if (this.expectedAuthorities != null) {
|
||||
AssertionErrors.assertTrue("Authentication cannot be null", auth != null);
|
||||
List<String> authorities = auth.getAuthorities()
|
||||
.stream()
|
||||
.filter(Predicate.not(this.ignoreAuthorities))
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.toList();
|
||||
AssertionErrors.assertTrue(
|
||||
authorities + " does not contain the same authorities as " + this.expectedAuthorities,
|
||||
this.expectedAuthorities.containsAll(authorities));
|
||||
AssertionErrors.assertTrue(
|
||||
this.expectedAuthorities + " does not contain the same authorities as " + authorities,
|
||||
authorities.containsAll(this.expectedAuthorities));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,6 +224,17 @@ public final class SecurityMockMvcResultMatchers {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the {@link GrantedAuthority#getAuthority()}
|
||||
* @param authorities the authorityNames
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
public AuthenticatedMatcher withAuthorities(String... authorities) {
|
||||
Assert.notNull(authorities, "authorities cannot be null");
|
||||
this.expectedAuthorities = Arrays.asList(authorities);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the {@link Authentication#getAuthorities()}
|
||||
* @param expected the {@link Authentication#getAuthorities()}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.core.GrantedAuthorities;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
@ -53,6 +54,8 @@ import static org.springframework.security.test.web.servlet.setup.SecurityMockMv
|
|||
@WebAppConfiguration
|
||||
public class SecurityMockWithAuthoritiesMvcResultMatchersTests {
|
||||
|
||||
private static final String ROLE_CUSTOM = "ROLE_CUSTOM";
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
|
@ -80,6 +83,12 @@ public class SecurityMockWithAuthoritiesMvcResultMatchersTests {
|
|||
() -> this.mockMvc.perform(formLogin()).andExpect(authenticated().withAuthorities(grantedAuthorities)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withAuthoritiesStringSupportsCustomAuthority() throws Exception {
|
||||
this.mockMvc.perform(formLogin().user("custom"))
|
||||
.andExpect(authenticated().withAuthorities(ROLE_CUSTOM, GrantedAuthorities.FACTOR_PASSWORD_AUTHORITY));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableWebMvc
|
||||
|
@ -89,7 +98,8 @@ public class SecurityMockWithAuthoritiesMvcResultMatchersTests {
|
|||
UserDetailsService userDetailsService() {
|
||||
// @formatter:off
|
||||
UserDetails user = User.withDefaultPasswordEncoder().username("user").password("password").roles("ADMIN", "SELLER").build();
|
||||
return new InMemoryUserDetailsManager(user);
|
||||
UserDetails customAuthorityUser = User.withDefaultPasswordEncoder().username("custom").password("password").authorities(new CustomAuthority(ROLE_CUSTOM)).build();
|
||||
return new InMemoryUserDetailsManager(user, customAuthorityUser);
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
|
@ -105,4 +115,25 @@ public class SecurityMockWithAuthoritiesMvcResultMatchersTests {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom {@link GrantedAuthority} for testing.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 7.0
|
||||
*/
|
||||
static class CustomAuthority implements GrantedAuthority {
|
||||
|
||||
private final String authority;
|
||||
|
||||
CustomAuthority(String authority) {
|
||||
this.authority = authority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return this.authority;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue