1818
1919import java .util .List ;
2020
21+ import com .fasterxml .jackson .databind .JsonNode ;
22+ import com .fasterxml .jackson .databind .ObjectMapper ;
2123import org .junit .jupiter .api .Test ;
2224import org .junit .jupiter .api .extension .ExtendWith ;
2325
2426import org .springframework .beans .factory .annotation .Autowired ;
2527import org .springframework .context .annotation .Bean ;
2628import org .springframework .context .annotation .Configuration ;
29+ import org .springframework .security .authentication .TestingAuthenticationToken ;
2730import org .springframework .security .config .Customizer ;
2831import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
2932import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
3841
3942import static org .assertj .core .api .Assertions .assertThat ;
4043import static org .hamcrest .Matchers .containsString ;
44+ import static org .springframework .security .test .web .servlet .request .SecurityMockMvcRequestPostProcessors .authentication ;
45+ import static org .springframework .security .test .web .servlet .request .SecurityMockMvcRequestPostProcessors .csrf ;
4146import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .get ;
47+ import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .post ;
4248import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .content ;
4349import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .header ;
4450import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .status ;
@@ -111,6 +117,42 @@ public void webauthnWhenFormLoginAndDefaultRegistrationPageConfiguredThenNoDupli
111117 .hasSize (1 );
112118 }
113119
120+ @ Test
121+ void webauthnWhenConfiguredDefaultsRpNameToRpId () throws Exception {
122+ ObjectMapper mapper = new ObjectMapper ();
123+ this .spring .register (DefaultWebauthnConfiguration .class ).autowire ();
124+ String response = this .mvc
125+ .perform (post ("/webauthn/register/options" ).with (csrf ())
126+ .with (authentication (new TestingAuthenticationToken ("test" , "ignored" , "ROLE_user" ))))
127+ .andExpect (status ().is2xxSuccessful ())
128+ .andReturn ()
129+ .getResponse ()
130+ .getContentAsString ();
131+
132+ JsonNode parsedResponse = mapper .readTree (response );
133+
134+ assertThat (parsedResponse .get ("rp" ).get ("id" ).asText ()).isEqualTo ("example.com" );
135+ assertThat (parsedResponse .get ("rp" ).get ("name" ).asText ()).isEqualTo ("example.com" );
136+ }
137+
138+ @ Test
139+ void webauthnWhenRpNameConfiguredUsesRpName () throws Exception {
140+ ObjectMapper mapper = new ObjectMapper ();
141+ this .spring .register (CustomRpNameWebauthnConfiguration .class ).autowire ();
142+ String response = this .mvc
143+ .perform (post ("/webauthn/register/options" ).with (csrf ())
144+ .with (authentication (new TestingAuthenticationToken ("test" , "ignored" , "ROLE_user" ))))
145+ .andExpect (status ().is2xxSuccessful ())
146+ .andReturn ()
147+ .getResponse ()
148+ .getContentAsString ();
149+
150+ JsonNode parsedResponse = mapper .readTree (response );
151+
152+ assertThat (parsedResponse .get ("rp" ).get ("id" ).asText ()).isEqualTo ("example.com" );
153+ assertThat (parsedResponse .get ("rp" ).get ("name" ).asText ()).isEqualTo ("Test RP Name" );
154+ }
155+
114156 @ Test
115157 public void webauthnWhenConfiguredAndFormLoginThenDoesServesJavascript () throws Exception {
116158 this .spring .register (FormLoginAndNoDefaultRegistrationPageConfiguration .class ).autowire ();
@@ -137,7 +179,27 @@ UserDetailsService userDetailsService() {
137179
138180 @ Bean
139181 SecurityFilterChain securityFilterChain (HttpSecurity http ) throws Exception {
140- return http .formLogin (Customizer .withDefaults ()).webAuthn (Customizer .withDefaults ()).build ();
182+ return http .formLogin (Customizer .withDefaults ())
183+ .webAuthn ((webauthn ) -> webauthn .rpId ("example.com" ))
184+ .build ();
185+ }
186+
187+ }
188+
189+ @ Configuration
190+ @ EnableWebSecurity
191+ static class CustomRpNameWebauthnConfiguration {
192+
193+ @ Bean
194+ UserDetailsService userDetailsService () {
195+ return new InMemoryUserDetailsManager ();
196+ }
197+
198+ @ Bean
199+ SecurityFilterChain securityFilterChain (HttpSecurity http ) throws Exception {
200+ return http .formLogin (Customizer .withDefaults ())
201+ .webAuthn ((webauthn ) -> webauthn .rpId ("example.com" ).rpName ("Test RP Name" ))
202+ .build ();
141203 }
142204
143205 }
0 commit comments