My IDE reports two errors in the following class: 1.WebSecurityConfigurerAdapter is a deprecated class; 2.Could not autowire. No beans of 'DataSource' type found. Locally the code works but I would still like to update the class with the new specifications. The code "private DataSource dataSource;" by IntelliJ in red worries me a lot. How should I rewrite this class?
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
public class ConfigurazioneSpringSecurity extends WebSecurityConfigurerAdapter {
@Autowired
LivelliDeiRuoli livelliDeiRuoli;
@Autowired
GestioneUtentiSpringSecurity gestioneUtentiSpringSecurity;
@Bean
public static BCryptPasswordEncoder metodoCrittografia() {
return new BCryptPasswordEncoder();
}
@Autowired
public void crittografiaPassword(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(gestioneUtentiSpringSecurity).passwordEncoder(metodoCrittografia());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
http.authorizeRequests().antMatchers(
"/",
"/login",
"/benvenuto",
"/registrazione",
"/registrazione-eseguita",
"/cookie",
"/contatti",
"logout"
).permitAll();
// ... etc...
http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/errore-403");
http.authorizeRequests().and().formLogin()
.loginProcessingUrl("/pagina-login")
.loginPage("/login")
.defaultSuccessUrl("/")
.failureUrl("/login?errore=true")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutUrl("/pagina-logout")
.logoutSuccessUrl("/login?logout=true");
http.authorizeRequests().and() //
.rememberMe().tokenRepository(this.persistentTokenRepository()) //
.tokenValiditySeconds(365 * 24 * 60 * 60);
http.authorizeRequests().antMatchers("/nome-pagina")
.access("hasAnyRole('" + livelliDeiRuoli.elencoRuoli(2L) + "')");
// ... etc...
}
@Autowired
private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
I updated the class by reading the following official documentation but in the page I found there are deprecated classes and methods.
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
I think I have everything corrected but it remains to understand how to configure Spring Security so that the "remember my password" button works. I have marked the code with question marks. I use PostgreSQL as a database and I put the database connection parameters in the .properties files. Here is the new class code:
@Configuration
@EnableWebSecurity
public class ConfigurazioneSpringSecurity {
@Autowired
LivelliDeiRuoli livelliDeiRuoli;
@Autowired
GestioneUtentiSpringSecurity gestioneUtentiSpringSecurity;
// ??? (code 1)
@Autowired
private DataSource dataSource;
// ??? (code 2)
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
// ??? (code 3)
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public static BCryptPasswordEncoder metodoCrittografia() {
return new BCryptPasswordEncoder();
}
@Autowired
public void crittografiaPassword(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(gestioneUtentiSpringSecurity).passwordEncoder(metodoCrittografia());
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// I am in doubt whether to use the code above or the code below
// but the one above worked in the past and was not deprecated.
// http.csrf().csrfTokenRepository(new HttpSessionCsrfTokenRepository()); ()
// ??? (code 4)
http.authorizeRequests().and()
.rememberMe().tokenRepository(this.persistentTokenRepository())
.tokenValiditySeconds(365 * 24 * 60 * 60);
http.authorizeRequests().antMatchers(
"/",
"/login",
"/benvenuto",
"/registrazione",
"/registrazione-eseguita",
"/cookie",
"/contatti",
"logout"
).permitAll();
http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/errore-403");
http.authorizeRequests().and().formLogin()
.loginProcessingUrl("/pagina-login")
.loginPage("/login")
.defaultSuccessUrl("/")
.failureUrl("/login?errore=true")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutUrl("/pagina-logout")
.logoutSuccessUrl("/login?logout=true");
http.authorizeRequests().antMatchers("/page1")
.access("hasAnyRole('" + livelliDeiRuoli.elencoRuoli(1L) + "')");
http.authorizeRequests().antMatchers("/page2")
.access("hasAnyRole('" + livelliDeiRuoli.elencoRuoli(2L) + "')");
// http. etc...
http.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated()).httpBasic(withDefaults());
return http.build();
}
}
With codes 1, 2, 3 and 4 I get a compile error:
java: method does not override or implement a method from a supertype
Without the codes 1, 2, 3 and 4 I get a WebApp startup error:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.0)
2022-05-31 14:51:58.455 INFO 3768 --- [ restartedMain] i.a.g.GestioneUtentiApplication : Starting GestioneUtentiApplication using Java 11.0.15 on EB-DESKTOP with PID 3768 (...\target\classes ...)
2022-05-31 14:51:58.456 INFO 3768 --- [ restartedMain] i.a.g.GestioneUtentiApplication : The following 1 profile is active: "sviluppo"
2022-05-31 14:51:58.495 INFO 3768 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2022-05-31 14:51:58.496 INFO 3768 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2022-05-31 14:51:59.690 INFO 3768 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8443 (https) 8080 (http)
2022-05-31 14:51:59.703 INFO 3768 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-05-31 14:51:59.703 INFO 3768 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.63]
2022-05-31 14:51:59.762 INFO 3768 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/it] : Initializing Spring embedded WebApplicationContext
2022-05-31 14:51:59.762 INFO 3768 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1266 ms
2022-05-31 14:51:59.833 INFO 3768 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-05-31 14:51:59.967 INFO 3768 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-05-31 14:52:00.351 WARN 3768 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'controlloPagineWeb': Unsatisfied dependency expressed through field 'authManager'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.authentication.AuthenticationManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2022-05-31 14:52:00.352 INFO 3768 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2022-05-31 14:52:00.372 INFO 3768 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2022-05-31 14:52:00.375 INFO 3768 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2022-05-31 14:52:00.385 INFO 3768 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-05-31 14:52:00.403 ERROR 3768 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field authManager in it.applicazionijava.gestioneutenti.pagine_web_spring_boot.ControlloPagineWeb required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.security.authentication.AuthenticationManager' in your configuration.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.437 s
[INFO] Finished at: 2022-05-31T14:52:00+02:00
[INFO] ------------------------------------------------------------------------
Process finished with exit code 0
I believe it is some bug in the framework. I also opened a Stackoverflow thread with no success.
https://stackoverflow.com/questions/72427751/update-the-spring-security-configuration-class-with-spring-boot-2-7-0
Thanks for the support Federico
Comment From: scottfrederick
Thanks for getting in touch. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements. SInce you've already started a question on StackOverflow, and people are trying to help you there, we'll close this issue. We can re-open it if you confirm that there is a problem in Spring Boot (and not in Spring Security or another project).
Comment From: fedegibut
Thanks for replying. If you want to intervene in the discussion you are welcome. I didn't get an answer on the other site. It is a pity that a beautiful framework like Spring Boot cannot be used / updated. On the documentation I have not found a solution to my problem and neither on the forums. This is all a real shame.