Skip to content

Commit

Permalink
Merge pull request #1406 from webauthn4j/dependabot/gradle/springBoot…
Browse files Browse the repository at this point in the history
…Version-3.2.5

chore(deps): bump springBootVersion from 3.0.5 to 3.2.5
  • Loading branch information
ynojima authored Apr 28, 2024
2 parents cc1e47e + dc63853 commit c0d7026
Show file tree
Hide file tree
Showing 10 changed files with 272 additions and 213 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
buildscript {
ext{
//Plugins
springBootVersion = '3.0.5'
springBootVersion = '3.2.5'
sonarqubeVersion = '5.0.0.4638'
asciidoctorGradleVersion = "4.0.2"
artifactoryVersion = '5.2.0'
Expand Down
62 changes: 39 additions & 23 deletions docs/src/reference/asciidoc/en/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,36 @@ public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
http.authenticationManager(authenticationManager);
// WebAuthn Login
http.apply(WebAuthnLoginConfigurer.webAuthnLogin())
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("rawPassword")
.credentialIdParameter("credentialId")
.clientDataJSONParameter("clientDataJSON")
.authenticatorDataParameter("authenticatorData")
.signatureParameter("signature")
.clientExtensionsJSONParameter("clientExtensionsJSON")
.loginProcessingUrl("/login")
.rpId("example.com")
.attestationOptionsEndpoint()
.attestationOptionsProvider(attestationOptionsProvider)
.and()
.assertionOptionsEndpoint()
.assertionOptionsProvider(assertionOptionsProvider)
.and()
.authenticationManager(authenticationManager);
http.with(WebAuthnLoginConfigurer.webAuthnLogin(), (customizer) ->{
customizer
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.credentialIdParameter("credentialId")
.clientDataJSONParameter("clientDataJSON")
.authenticatorDataParameter("authenticatorData")
.signatureParameter("signature")
.clientExtensionsJSONParameter("clientExtensionsJSON")
.loginProcessingUrl("/login")
.attestationOptionsEndpoint()
.rp()
.name("WebAuthn4J Spring Security Sample")
.and()
.pubKeyCredParams(
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.RS256), // Windows Hello
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256) // FIDO U2F Key, etc
)
.extensions()
.credProps(true)
.and()
.assertionOptionsEndpoint()
.and()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler);
});
}
}
----
Expand Down Expand Up @@ -144,8 +155,10 @@ public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
http.authenticationManager(authenticationManager);
// WebAuthn Login
http.apply(WebAuthnLoginConfigurer.webAuthnLogin())
http.with(WebAuthnLoginConfigurer.webAuthnLogin(), (customizer) ->{
customizer
.rpId("example.com")
.attestationOptionsEndpoint()
.attestationOptionsProvider(attestationOptionsProvider)
Expand All @@ -172,8 +185,8 @@ public class WebSecurityConfig {
.processingUrl("/webauthn/assertion/options")
.rpId("example.com")
.userVerification(UserVerificationRequirement.PREFERRED)
.and()
.authenticationManager(authenticationManager);
.and();
});
}
}
Expand All @@ -192,13 +205,16 @@ public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
// WebAuthn Login
http.apply(WebAuthnLoginConfigurer.webAuthnLogin())
http.with(WebAuthnLoginConfigurer.webAuthnLogin(), (customizer) ->{
customizer
.attestationOptionsEndpoint()
.attestationOptionsProvider(attestationOptionsProvider)
.processingUrl("/webauthn/attestation/options")
.processingUrl("/webauthn/attestation/options")
.user(new MyPublicKeyCredentialUserEntityProvider()) // put your PublicKeyCredentialUserEntityProvider implementation
.user(new MyPublicKeyCredentialUserEntityProvider()); // put your PublicKeyCredentialUserEntityProvider implementation
});
}
}
----
Expand Down
62 changes: 39 additions & 23 deletions docs/src/reference/asciidoc/ja/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,36 @@ public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
http.authenticationManager(authenticationManager);
// WebAuthn Login
http.apply(WebAuthnLoginConfigurer.webAuthnLogin())
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("rawPassword")
.credentialIdParameter("credentialId")
.clientDataJSONParameter("clientDataJSON")
.authenticatorDataParameter("authenticatorData")
.signatureParameter("signature")
.clientExtensionsJSONParameter("clientExtensionsJSON")
.loginProcessingUrl("/login")
.rpId("example.com")
.attestationOptionsEndpoint()
.attestationOptionsProvider(attestationOptionsProvider)
.and()
.assertionOptionsEndpoint()
.assertionOptionsProvider(assertionOptionsProvider)
.and()
.authenticationManager(authenticationManager);
http.with(WebAuthnLoginConfigurer.webAuthnLogin(), (customizer) ->{
customizer
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.credentialIdParameter("credentialId")
.clientDataJSONParameter("clientDataJSON")
.authenticatorDataParameter("authenticatorData")
.signatureParameter("signature")
.clientExtensionsJSONParameter("clientExtensionsJSON")
.loginProcessingUrl("/login")
.attestationOptionsEndpoint()
.rp()
.name("WebAuthn4J Spring Security Sample")
.and()
.pubKeyCredParams(
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.RS256), // Windows Hello
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256) // FIDO U2F Key, etc
)
.extensions()
.credProps(true)
.and()
.assertionOptionsEndpoint()
.and()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler);
});
}
}
----
Expand Down Expand Up @@ -149,8 +160,10 @@ public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
http.authenticationManager(authenticationManager);
// WebAuthn Login
http.apply(WebAuthnLoginConfigurer.webAuthnLogin())
http.with(WebAuthnLoginConfigurer.webAuthnLogin(), (customizer) ->{
customizer
.rpId("example.com")
.attestationOptionsEndpoint()
.attestationOptionsProvider(attestationOptionsProvider)
Expand All @@ -177,8 +190,8 @@ public class WebSecurityConfig {
.processingUrl("/webauthn/assertion/options")
.rpId("example.com")
.userVerification(UserVerificationRequirement.PREFERRED)
.and()
.authenticationManager(authenticationManager);
.and();
});
}
}
----
Expand All @@ -197,13 +210,16 @@ public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
// WebAuthn Login
http.apply(WebAuthnLoginConfigurer.webAuthnLogin())
http.with(WebAuthnLoginConfigurer.webAuthnLogin(), (customizer) ->{
customizer
.attestationOptionsEndpoint()
.attestationOptionsProvider(attestationOptionsProvider)
.processingUrl("/webauthn/attestation/options")
.processingUrl("/webauthn/attestation/options")
.user(new MyPublicKeyCredentialUserEntityProvider()) // put your PublicKeyCredentialUserEntityProvider implementation
.user(new MyPublicKeyCredentialUserEntityProvider()); // put your PublicKeyCredentialUserEntityProvider implementation
});
}
}
----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,23 +113,25 @@ public WebSecurityCustomizer webSecurityCustomizer() {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
// WebAuthn Config
http.apply(WebAuthnLoginConfigurer.webAuthnLogin())
.attestationOptionsEndpoint()
.rp()
.name("WebAuthn4J Spring Security Sample")
.and()
.pubKeyCredParams(
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256),
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.RS1),
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.EdDSA)
)
.extensions()
.entry("example.extension", "test")
.and()
.assertionOptionsEndpoint()
.extensions()
.entry("example.extension", "test")
.and();
http.with(WebAuthnLoginConfigurer.webAuthnLogin(), (customizer)->{
customizer
.attestationOptionsEndpoint()
.rp()
.name("WebAuthn4J Spring Security Sample")
.and()
.pubKeyCredParams(
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256),
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.RS1),
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.EdDSA)
)
.extensions()
.entry("example.extension", "test")
.and()
.assertionOptionsEndpoint()
.extensions()
.entry("example.extension", "test")
.and();
});

FidoServerAttestationOptionsEndpointFilter fidoServerAttestationOptionsEndpointFilter = new FidoServerAttestationOptionsEndpointFilter(objectConverter, attestationOptionsProvider, challengeRepository);
FidoServerAttestationResultEndpointFilter fidoServerAttestationResultEndpointFilter = new FidoServerAttestationResultEndpointFilter(objectConverter, userDetailsManager, webAuthnAuthenticatorManager, webAuthnRegistrationRequestValidator);
Expand All @@ -144,21 +146,25 @@ public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager
http.addFilterAfter(fidoServerAssertionResultEndpointFilter, SessionManagementFilter.class);

// Authorization
http.authorizeHttpRequests()
.requestMatchers("/").permitAll()
.requestMatchers("/api/auth/status").permitAll()
.requestMatchers(HttpMethod.GET, "/login").permitAll()
.requestMatchers(HttpMethod.POST, "/api/profile").permitAll()
.requestMatchers("/health/**").permitAll()
.requestMatchers("/info/**").permitAll()
.requestMatchers("/h2-console/**").denyAll()
.requestMatchers("/api/admin/**").hasRole(ADMIN_ROLE)
.anyRequest().fullyAuthenticated();
http.authorizeHttpRequests(customizer -> {
customizer
.requestMatchers("/").permitAll()
.requestMatchers("/api/auth/status").permitAll()
.requestMatchers(HttpMethod.GET, "/login").permitAll()
.requestMatchers(HttpMethod.POST, "/api/profile").permitAll()
.requestMatchers("/health/**").permitAll()
.requestMatchers("/info/**").permitAll()
.requestMatchers("/h2-console/**").denyAll()
.requestMatchers("/api/admin/**").hasRole(ADMIN_ROLE)
.anyRequest().fullyAuthenticated();
});

//TODO:
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

http.csrf().ignoringRequestMatchers("/webauthn/**");
//TODO:
http.csrf(customizer -> {
customizer.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
customizer.ignoringRequestMatchers("/webauthn/**");
});

http.authenticationManager(authenticationManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
Expand Down Expand Up @@ -86,32 +87,34 @@ public WebSecurityCustomizer webSecurityCustomizer() {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
// WebAuthn Login
http.apply(WebAuthnLoginConfigurer.webAuthnLogin())
.defaultSuccessUrl("/", true)
.failureUrl("/login")
.attestationOptionsEndpoint()
.rp()
.name("WebAuthn4J Spring Security Sample")
.and()
.pubKeyCredParams(
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256),
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.RS1)
)
.attestation(AttestationConveyancePreference.NONE)
.extensions()
.uvm(true)
.credProps(true)
.extensionProviders()
.and()
.assertionOptionsEndpoint()
.extensions()
.extensionProviders();
http.with(WebAuthnLoginConfigurer.webAuthnLogin(), (customizer)-> {
customizer
.defaultSuccessUrl("/", true)
.failureUrl("/login")
.attestationOptionsEndpoint()
.rp()
.name("WebAuthn4J Spring Security Sample")
.and()
.pubKeyCredParams(
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256),
new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.RS1)
)
.attestation(AttestationConveyancePreference.NONE)
.extensions()
.uvm(true)
.credProps(true)
.extensionProviders()
.and()
.assertionOptionsEndpoint()
.extensions()
.extensionProviders();
});

http.headers(headers -> {
// 'publickey-credentials-get *' allows getting WebAuthn credentials to all nested browsing contexts (iframes) regardless of their origin.
headers.permissionsPolicy(config -> config.policy("publickey-credentials-get *"));
// Disable "X-Frame-Options" to allow cross-origin iframe access
headers.frameOptions().disable();
headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable);
});


Expand All @@ -123,14 +126,18 @@ public SecurityFilterChain filterChain(HttpSecurity http, AuthenticationManager
.anyRequest().access(getWebExpressionAuthorizationManager("@webAuthnSecurityExpression.isWebAuthnAuthenticated(authentication) || hasAuthority('SINGLE_FACTOR_AUTHN_ALLOWED')"))
);

http.exceptionHandling()
.accessDeniedHandler((request, response, accessDeniedException) -> response.sendRedirect("/login"));
http.exceptionHandling(customizer -> {
customizer.accessDeniedHandler((request, response, accessDeniedException) -> response.sendRedirect("/login"));
});


http.authenticationManager(authenticationManager);

// As WebAuthn has its own CSRF protection mechanism (challenge), CSRF token is disabled here
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
http.csrf().ignoringRequestMatchers("/webauthn/**");
http.csrf(customizer -> {
customizer.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
customizer.ignoringRequestMatchers("/webauthn/**");
});

return http.build();

Expand Down
Loading

0 comments on commit c0d7026

Please sign in to comment.