for some reason the authenticationManager is not being added to the context, that's what I imagine, because I'm getting an error: "Factory method 'authorizationServerSecurityFilterChain' threw exception with message: authenticationManager cannot be null"
I've tried to add the line, but I get that authenticationManager as a parameter cannot be resolved symbol.
http.authenticationManager(authenticationManager);
I don't know if I'm forgetting to do something in this spring security oauth configuration. The Authorization server version (1.4.1) spring boot (3.4.2) and Java 17. I appreciate any help.
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public UserDetailsService userDetailsService(UserRepository userRepository) {
return new CustomUserDetailsService(userRepository);
}
@Bean
public AuthenticationManager authenticationManager(
UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder) {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder);
return new ProviderManager(authProvider);
}
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.authorizeHttpRequests(authorize -> authorize.anyRequest().authenticated())
.csrf(AbstractHttpConfigurer::disable)
.formLogin(Customizer.withDefaults());
authorizationServerConfigurer.configure(http);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/api/auth/register").permitAll()
.anyRequest().authenticated()
)
.csrf(csrf -> csrf.ignoringRequestMatchers("/api/auth/register"))
.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable);
return http.build();
}
... more code
I can't see that I have a custom AuthenticationManager
bean in my authorization server.
I suspect there might be several issues here, but let's start with what I have and see if you can use that as a base. Code is based on this part of Spring Authorization Server docs.
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
var authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, authorizationServer ->
authorizationServer.oidc(Customizer.withDefaults())
)
.authorizeHttpRequests(authorize ->
authorize.anyRequest().authenticated()
)
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling(exceptions -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
);
return http.build();
}
@Bean
@Order(2)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
// remove this if you don't have actuator endpoints
.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll()
.anyRequest().authenticated()
)
// replace this with your URL
.logout(logout -> logout.logoutSuccessUrl("http://localhost:3000/"))
.formLogin(Customizer.withDefaults());
return http.build();
}
}