Spring Security - MacKittipat/note-developer GitHub Wiki
Spring Security
Architecture
Ref : http://shazsterblog.blogspot.com/2018/10/spring-security-authentication-security.html
Ref : https://docs.gigaspaces.com/latest/security/introducing-spring-security.html
Ref : https://springbootdev.com/2017/08/23/spring-security-authentication-architecture/
Example
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/user").hasAnyRole("USER", "ADMIN")
.antMatchers("/admin").hasAnyRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
auth.inMemoryAuthentication()
.withUser("mac")
.password(bCryptPasswordEncoder.encode("password"))
.roles("USER")
.and()
.withUser("admin")
.password(bCryptPasswordEncoder.encode("password"))
.roles("ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Explanation :
- Open http://localhost:8080/user, browser will redirect to /login page
- After enter user and pass and click login,
UsernamePasswordAuthenticationFilter.attemptAuthentication()
will intercept the request. It can intercept login page because there is path configuration in constructor.
public UsernamePasswordAuthenticationFilter() {
super(new AntPathRequestMatcher("/login", "POST"));
}
- In
UsernamePasswordAuthenticationFilter
,this.getAuthenticationManager().authenticate(authRequest)
will callProviderManager.authenticate()
- In
ProviderManager
,provider.authenticate(authentication);
will callDaoAuthenticationProvider.authenticate()
to check username and password.
Filter
DelegatingFilterProxy
use FilterChainProxy
to execute filter in order from WebAsyncManagerIntegrationFilter
to FilterSecurityInterceptor
Execute order
DelegatingFilterProxy.doFilter()
->
FilterChainProxy.doFilter()
->
WebAsyncManagerIntegrationFilter.doFilter()
->
SecurityContextPersistenceFilter.doFilter()
->
...
(AbstractAuthenticationProcessingFilter.doFilter()
-> UsernamePasswordAuthenticationFilter.attemptAuthentication()
)
...