Testen von Spring Boot Security einfach
Ich habe Mühe mit dem testen der Zugriffssteuerung auf URLs, geschützt durch Spring Security.
Die Konfiguration sieht so aus:
http
.authorizeRequests()
.antMatchers("/api/user/**", "/user").authenticated()
.antMatchers("/api/admin/**", "/templates/admin/**", "/admin/**").hasAuthority("ADMIN")
.anyRequest().permitAll();
Und der test-Klasse sieht wie folgt aus:
package com.kubukoz.myapp;
import com.kubukoz.myapp.config.WebSecurityConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import javax.transaction.Transactional;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {MyApplication.class, WebSecurityConfig.class})
@WebAppConfiguration
@TransactionConfiguration(defaultRollback = true)
@Transactional(rollbackOn = Exception.class)
public class MyApplicationTests {
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Autowired
private FilterChainProxy filterChainProxy;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.dispatchOptions(true)
.addFilters(filterChainProxy)
.build();
}
@Test
public void testAnonymous() throws Exception {
mockMvc.perform(get("/api/user/account")).andExpect(status().is3xxRedirection());
}
@Test
public void testUserAccessForAccount() throws Exception{
mockMvc.perform(get("/api/user/account")).andExpect(status().isOk());
}
}
Was ist der einfachste Weg, um die letzten beiden tests bestehen?
@WithMockUser hat nicht funktioniert.
- Versucht durch kommentieren Sie Ihre Methoden mit
@PreAuthorize("hasPermission('ADMIN')")
- Klingt wie die Wiederholung von code, wie ich bereits autorisieren Sie in der security-Konfiguration, und es funktioniert - mit tatsächlichen Benutzern, nicht in tests
- Ich kann nicht autowire-filter-proxy-Kette, was mache ich falsch?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie nicht fügen Sie die FilterChainProxy direkt. Stattdessen sollten Sie sich bewerben
SecurityMockMvcConfigurers.springSecurity()
wie von die Referenz. Ein Beispiel wird unten aufgeführt:Ist die Folge:
FilterChainProxy
ist nun alsFilter
zuMockMvc
(wie du hast)TestSecurityContextHolderPostProcessor
HinzugefügtWarum ist
TestSecurityContextHolderPostProcessor
notwendig? Der Grund dafür ist, dass wir kommunizieren müssen, die dem aktuellen Benutzer aus der test-Methode, um dieMockHttpServletRequest
erstellt wird. Dies ist notwendig, da Spring Security istSecurityContextRepositoryFilter
überschreibt jeden Wert aufSecurityContextHolder
zu den gefundenen Wert durch den aktuellenSecurityContextRepository
(d.h. dieSecurityContext
imHttpSession
).Update
Erinnern, enthält alles, was die Rolle in der Methode den Namen automatisch das Präfix "ROLE_" die Zeichenfolge, die übergeben wurde.
Basierend auf Ihren Kommentar, das problem ist, müssen Sie entweder aktualisieren Sie Ihre Konfiguration zu verwenden hasRole statt hasAuthority (da Ihre Anmerkung ist mit Rollen):
Alternativ
Im Frühjahr Security 4.0.2+ können Sie:
roles
zuauthorities
hier nicht helfen - immer ein 302 auf /login dieser Zeit. Ich habe ein gradle-Abhängigkeit für spring-security-web:4.0.2.RELEASE.Okay, kapiert.
Funktioniert es jetzt.
@WithMockUser(roles="ADMIN")
wie in der referenzierten Dokumentationorg.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user
, wahrscheinlich aus derspring-security-test
Bibliothek..with(user("user"))
ignoriert jede Art von Genehmigung oder Rollen-basierte Sicherheit