Skip to content

Commit 06917fb

Browse files
committed
Add documentation for configuring public endpoints
1 parent fe9edc8 commit 06917fb

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

docs/modules/ROOT/pages/servlet/architecture.adoc

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,136 @@ In the event that you are unable to reconfigure `HttpSecurity` to not add a cert
562562
----
563563
====
564564

565+
[[servlet-public-endpoints]]
566+
== Configuring Public Endpoints
567+
568+
There are often endpoints that need to be accessible without authentication, such as login pages, public assets, or public APIs. The `@SecurityFilterChain` API allows you to configure which endpoints should be publicly accessible.
569+
570+
Let's look at how to configure endpoints to allow public access:
571+
572+
[tabs]
573+
======
574+
Java::
575+
+
576+
[source,java,role="primary"]
577+
----
578+
@Bean
579+
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
580+
http
581+
.csrf(Customizer.withDefaults())
582+
.httpBasic(Customizer.withDefaults())
583+
.authorizeHttpRequests(authorize -> authorize
584+
// Public endpoints
585+
.requestMatchers("/public/**", "/error").permitAll()
586+
.requestMatchers(HttpMethod.GET, "/actuator/health").permitAll()
587+
// Secure everything else
588+
.anyRequest().authenticated()
589+
);
590+
return http.build();
591+
}
592+
----
593+
594+
Kotlin::
595+
+
596+
[source,kotlin,role="secondary"]
597+
----
598+
@Bean
599+
fun filterChain(http: HttpSecurity): SecurityFilterChain {
600+
http {
601+
csrf { }
602+
httpBasic { }
603+
authorizeHttpRequests {
604+
// Public endpoints
605+
requestMatchers("/public/**", "/error").permitAll()
606+
requestMatchers(HttpMethod.GET, "/actuator/health").permitAll()
607+
// Secure everything else
608+
anyRequest().authenticated()
609+
}
610+
}
611+
return http.build()
612+
}
613+
----
614+
615+
======
616+
617+
[NOTE]
618+
====
619+
If a request presents credentials (tokens, Basic Auth, etc.), Spring Security will attempt to authenticate the user even when an endpoint is configured with `permitAll()`.
620+
====
621+
622+
623+
[TIP]
624+
By using the `@Order` annotation, you can define separate security filter chains for public and secured endpoints.
625+
Filter chains with lower order numbers are evaluated first.
626+
627+
628+
[tabs]
629+
======
630+
Java::
631+
+
632+
[source,java,role="primary"]
633+
----
634+
@Bean
635+
@Order(1)
636+
public SecurityFilterChain publicFilterChain(HttpSecurity http) throws Exception {
637+
http
638+
.securityMatchers(matchers -> matchers
639+
.requestMatchers("/public/**", "/error", "/actuator/health")
640+
)
641+
.authorizeHttpRequests(authorize -> authorize
642+
.anyRequest().permitAll()
643+
);
644+
return http.build();
645+
}
646+
647+
@Bean
648+
@Order(2)
649+
public SecurityFilterChain protectedFilterChain(HttpSecurity http) throws Exception {
650+
http
651+
.csrf(Customizer.withDefaults())
652+
.httpBasic(Customizer.withDefaults())
653+
.authorizeHttpRequests(authorize -> authorize
654+
.anyRequest().authenticated()
655+
);
656+
return http.build();
657+
}
658+
659+
----
660+
661+
Kotlin::
662+
+
663+
[source,kotlin,role="secondary"]
664+
----
665+
@Bean
666+
@Order(1)
667+
fun publicFilterChain(http: HttpSecurity): SecurityFilterChain {
668+
http {
669+
securityMatchers {
670+
requestMatchers("/public/**", "/error", "/actuator/health")
671+
}
672+
authorizeHttpRequests {
673+
anyRequest().permitAll()
674+
}
675+
}
676+
return http.build()
677+
}
678+
679+
@Bean
680+
@Order(2)
681+
fun protectedFilterChain(http: HttpSecurity): SecurityFilterChain {
682+
http {
683+
csrf { }
684+
httpBasic { }
685+
authorizeHttpRequests {
686+
anyRequest().authenticated()
687+
}
688+
}
689+
return http.build()
690+
}
691+
----
692+
693+
======
694+
565695
[[servlet-exceptiontranslationfilter]]
566696
== Handling Security Exceptions
567697

0 commit comments

Comments
 (0)