webauthn: introduce DefaultResourcesFilter#webauthn

This commit is contained in:
Daniel Garnier-Moiroux 2024-10-22 14:46:15 +02:00 committed by Rob Winch
parent ca1f891f25
commit a1526361b6
2 changed files with 71 additions and 16 deletions

View File

@ -94,4 +94,21 @@ public final class DefaultResourcesFilter extends GenericFilterBean {
new MediaType("text", "css", StandardCharsets.UTF_8));
}
/**
* Create an instance of {@link DefaultResourcesFilter} serving Spring Security's
* default webauthn javascript.
* <p>
* The created {@link DefaultResourcesFilter} matches requests
* {@code HTTP GET /login/webauthn.js}, and returns the default webauthn javascript at
* {@code org/springframework/security/spring-security-webauthn.js} with content-type
* {@code text/javascript;charset=UTF-8}. This file is generated in the
* {@code spring-security-javascript} project.
* @return -
*/
public static DefaultResourcesFilter webauthn() {
return new DefaultResourcesFilter(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/login/webauthn.js"),
new ClassPathResource("org/springframework/security/spring-security-webauthn.js"),
new MediaType("text", "javascript", StandardCharsets.UTF_8));
}
}

View File

@ -16,6 +16,7 @@
package org.springframework.security.web.authentication.ui;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.MockMvc;
@ -33,27 +34,64 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*/
public class DefaultResourcesFilterTests {
private final DefaultResourcesFilter filter = DefaultResourcesFilter.css();
@Nested
class CssFilter {
private final MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new Object()).addFilters(this.filter).build();
private final DefaultResourcesFilter cssFilter = DefaultResourcesFilter.css();
private final MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new Object())
.addFilters(this.cssFilter)
.build();
@Test
void doFilterThenRender() throws Exception {
this.mockMvc.perform(get("/default-ui.css"))
.andExpect(status().isOk())
.andExpect(content().contentType("text/css;charset=UTF-8"))
.andExpect(content().string(containsString("body {")));
}
@Test
void doFilterWhenPathDoesNotMatchThenCallsThrough() throws Exception {
this.mockMvc.perform(get("/does-not-match")).andExpect(status().isNotFound());
}
@Test
void toStringPrintsPathAndResource() {
assertThat(this.cssFilter.toString()).isEqualTo(
"DefaultResourcesFilter [matcher=Ant [pattern='/default-ui.css', GET], resource=org/springframework/security/default-ui.css]");
}
@Test
public void doFilterThenRender() throws Exception {
this.mockMvc.perform(get("/default-ui.css"))
.andExpect(status().isOk())
.andExpect(content().contentType("text/css;charset=UTF-8"))
.andExpect(content().string(containsString("body {")));
}
@Test
public void doFilterWhenPathDoesNotMatchThenCallsThrough() throws Exception {
this.mockMvc.perform(get("/does-not-match")).andExpect(status().isNotFound());
}
@Nested
class WebAuthnFilter {
private final DefaultResourcesFilter webauthnFilter = DefaultResourcesFilter.webauthn();
private final MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new Object())
.addFilters(this.webauthnFilter)
.build();
@Test
void doFilterThenRender() throws Exception {
this.mockMvc.perform(get("/login/webauthn.js"))
.andExpect(status().isOk())
.andExpect(content().contentType("text/javascript;charset=UTF-8"))
.andExpect(content().string(containsString("async function authenticate(")));
}
@Test
void doFilterWhenPathDoesNotMatchThenCallsThrough() throws Exception {
this.mockMvc.perform(get("/does-not-match")).andExpect(status().isNotFound());
}
@Test
void toStringPrintsPathAndResource() {
assertThat(this.webauthnFilter.toString()).isEqualTo(
"DefaultResourcesFilter [matcher=Ant [pattern='/login/webauthn.js', GET], resource=org/springframework/security/spring-security-webauthn.js]");
}
@Test
void toStringPrintsPathAndResource() {
assertThat(this.filter.toString()).isEqualTo(
"DefaultResourcesFilter [matcher=Ant [pattern='/default-ui.css', GET], resource=org/springframework/security/default-ui.css]");
}
}