I am following the linked tutorial on spring security and I am not sure how to proceed with the configure method. https://youtube.com/watch?v=her_7pa0vrg&feature=shares&t=12491
The tutorial's repo has the code below:
package com.example.demo.security;
import com.example.demo.auth.ApplicationUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.util.concurrent.TimeUnit;
import static com.example.demo.security.ApplicationUserRole.*;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
private final PasswordEncoder passwordEncoder;
private final ApplicationUserService applicationUserService;
@Autowired
public ApplicationSecurityConfig(PasswordEncoder passwordEncoder,
ApplicationUserService applicationUserService) {
this.passwordEncoder = passwordEncoder;
this.applicationUserService = applicationUserService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "index", "/css/*", "/js/*").permitAll()
.antMatchers("/api/**").hasRole(STUDENT.name())
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.defaultSuccessUrl("/courses", true)
.passwordParameter("password")
.usernameParameter("username")
.and()
.rememberMe()
.tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(21))
.key("somethingverysecured")
.rememberMeParameter("remember-me")
.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET")) // https://docs.spring.io/spring-security/site/docs/4.2.12.RELEASE/apidocs/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.html
.clearAuthentication(true)
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID", "remember-me")
.logoutSuccessUrl("/login");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(applicationUserService);
return provider;
}
}
I am having trouble with this method:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
As the new way of doing things in Spring Security are per the reference page https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
My code looks like the below following the new conventions:
package com.quadri.springsecurity.security;
import static com.quadri.springsecurity.security.ApplicationUserRole.STUDENT;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import com.quadri.springsecurity.auth.ApplicationUserService;
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig {
private PasswordEncoder passwordEncoder;
private ApplicationUserService applicationUserService;
public ApplicationSecurityConfig(PasswordEncoder passwordEncoder, ApplicationUserService applicationUserService) {
this.passwordEncoder = passwordEncoder;
this.applicationUserService = applicationUserService;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers( "resources/**", "/", "/index.html").permitAll()
.requestMatchers("/api/**").hasRole(STUDENT.name())
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.defaultSuccessUrl("/courses", true)
.passwordParameter("password")
.usernameParameter("username")
.and()
.rememberMe()
.tokenValiditySeconds((int)TimeUnit.DAYS.toSeconds(21))
.key("somethingverysecured")
.rememberMeParameter("remember-me")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
.clearAuthentication(true)
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID", "remember-me")
.logoutSuccessUrl("/login")
;
return http.build();
}
//configure method I need to implement
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(applicationUserService);
return provider;
}
}
My users will be coming from this FakeApplicationUserDaoService:
package com.quadri.springsecurity.auth;
import static com.quadri.springsecurity.security.ApplicationUserRole.ADMIN;
import static com.quadri.springsecurity.security.ApplicationUserRole.ADMINTRAINEE;
import static com.quadri.springsecurity.security.ApplicationUserRole.STUDENT;
import java.util.List;
import java.util.Optional;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Repository;
import com.google.common.collect.Lists;
@Repository("fake")
public class FakeApplicationUserDaoService implements ApplicationUserDao {
private final PasswordEncoder passwordEncoder;
public FakeApplicationUserDaoService(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@Override
public Optional<ApplicationUser> selectApplicationUserByUsername(String username) {
return getApplicationUsers()
.stream()
.filter(applicationUser -> username.equals(applicationUser.getUsername()))
.findFirst();
}
private List<ApplicationUser> getApplicationUsers() {
return Lists.newArrayList
(
new ApplicationUser(
"annasmith",
passwordEncoder.encode("password1"),
STUDENT.getGrantedAuthorities(),
true,
true,
true,
true
),
new ApplicationUser(
"linda",
passwordEncoder.encode("password123"),
ADMIN.getGrantedAuthorities(),
true,
true,
true,
true
),
new ApplicationUser(
"tom",
passwordEncoder.encode("password123"),
ADMINTRAINEE.getGrantedAuthorities(),
true,
true,
true,
true
)
);
}
}
How do I implement the older convention method in my application using the newer style?
CodePudding user response:
Since this class doesn't extends/implements to any. There is no way to override this method void configure(AuthenticationManagerBuilder auth)
You can create that configure method without any annotation but make sure class gets this import
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(applicationUserService);
return provider;
}
public void configure( AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider( daoAuthenticationProvider());
}
CodePudding user response:
Spring Security picks up AuthenticationProvider
@Bean
s by default, so no additional code should be necessary. If that's not working, consider posting a GitHub minimal sample to clarify.
Or, you can publish your own AuthenticationManager
like so:
@Bean
AuthenticationManager authenticationManager(...) {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder);
provider.setUserDetailsService(applicationUserService);
return new ProviderManager(provider);
}