I have this `application.properties' file:
security.basic.enabled=false
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/appdata
spring.datasource.username=kleber
spring.datasource.password=123456
spring.datasource.continue-on-error=true
sprinf.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.file-size-threshold=10MB
server.tomcat.max-http-post-size=10MB
and this App class:
@SpringBootApplication
@Controller
public class AppApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AppApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppApplication.class);
}
@Bean
public WebSecurityCustomizer ignoringCustomizer() {
return (web) -> web
.ignoring()
.antMatchers("/", "/login", "/logout", "/register", "/error", "/css/**", "/js/**", "/img/**");
}
@Bean
public SpringSecurityDialect springSecurityDialect() {
return new SpringSecurityDialect();
}
@RequestMapping(value = "/")
public String index(Model model) {
return "index";
}
@RequestMapping(value = "/login")
public String login(Model model) {
return "login";
}
@RequestMapping(value = "/register", method=RequestMethod.GET)
public String register(Model model) {
model.addAttribute("obj", new Usuario());
return "register";
}
@RequestMapping(value = "/register", method=RequestMethod.POST)
public String register(@ModelAttribute Usuario usuario) {
return "redirect:/login";
}
}
I have tried add a Bean
to the class above, like that:
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() { ... }
}
@Bean PasswordEncoder passwordEncoder() {
return new PasswordEncoder() { ... }
}
but this do not work. My guess is I need some way to configure them in the method WebSecurityCustomizer ignoringCustomizer()
, but looking the documentation for the class WebSecurityCustomizer
I do not see any way to do that.
Anyone can give any hints of how to do that?
UPDATE #1
Searching through the official site, I found some reference documentation and blog post telling the recommended way to do some actions close to what I need, but I am still struggling to get right.
First link, it's the reference page for the deprecated class WebSecurityConfigurerAdapter
, where it's said to:
Use a SecurityFilterChain Bean to configure HttpSecurity or a WebSecurityCustomizer Bean to configure WebSecurity
HttpSecurity
have a method to define a UserDetailsService Bean, but how I use it in my code?
The other link it's a blog post describing the old way to do some authentication tasks, and the new recommended way. The closest examples to what I want it's in the section about JDBC Authentication
and In-Memory Authentication
, and both of them are based on the use of a UseDetailsManager, if I am not wrong. I also tried add a new Bean like that:
@Bean
public UserDetailsManager userDetailsManager() {
return new UserDetailsManager() { ... }
}
but does not work. What's the right way to do override the beans I want now?
UPDATE 2
I currently have this code, which is still not working properly. with this configuration, I can register a new user (which is created in the database with success), but I cannot login with this user.
@SpringBootApplication
@Controller
public class App extends SpringBootServletInitializer {
@Autowired
UsuarioDao usuarioDao;
@Autowired
CredencialDao credencialDao;
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
@Bean
public SpringSecurityDialect springSecurityDialect() {
return new SpringSecurityDialect();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().disable()
.authorizeRequests()
.antMatchers("/", "/login", "/logout", "/register", "/error", "/css/**", "/js/**", "/img/**").permitAll()
.anyRequest().authenticated()
.and()
.authenticationProvider(authProvider());
return http.build();
}
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(userDetailsService());
return provider;
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username) {
System.out.println("loadUserByUsername: " + username);
return usuarioDao.findBy("username", username).get(0);
}
};
}
@Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence rawPassword) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(rawPassword.toString().getBytes());
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for(int i=0; i<digest.length; i++) sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
return sb.toString();
} catch (Exception e) {
return null;
}
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return encodedPassword.equals(encode(rawPassword));
}
};
}
@RequestMapping(value = "/")
public String index(Model model) {
return "index";
}
@RequestMapping(value = "/login")
public String login(Model model) {
return "login";
}
@RequestMapping(value = "/register", method=RequestMethod.GET)
public String register(Model model) {
model.addAttribute("obj", new Usuario());
return "register";
}
@RequestMapping(value = "/register", method=RequestMethod.POST)
public String register(@ModelAttribute Usuario usuario) {
try {
usuario.setPassword(passwordEncoder().encode(usuario.getPassword()));
usuario.setCredenciais(new ArrayList<Credencial>());
usuario.getCredenciais().add(credencialDao.findBy("nome", "USER").get(0));
usuarioDao.insert(usuario);
return "login";
} catch (Exception e) {
e.printStackTrace();
return "register";
}
}
}