|
@@ -1,27 +1,90 @@
|
|
|
package cn.minbb.job.config;
|
|
|
|
|
|
+import cn.minbb.job.handler.LoginAuthenticationFailureHandler;
|
|
|
+import cn.minbb.job.handler.LoginAuthenticationSuccessHandler;
|
|
|
+import cn.minbb.job.handler.LogoutSuccessHandler;
|
|
|
+import cn.minbb.job.model.repository.UserRepository;
|
|
|
+import cn.minbb.job.service.impl.UserServiceImpl;
|
|
|
+import lombok.extern.log4j.Log4j2;
|
|
|
import org.springframework.context.annotation.Configuration;
|
|
|
import org.springframework.core.annotation.Order;
|
|
|
+import org.springframework.http.HttpMethod;
|
|
|
+import org.springframework.security.authentication.BadCredentialsException;
|
|
|
+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.builders.WebSecurity;
|
|
|
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.util.matcher.AntPathRequestMatcher;
|
|
|
|
|
|
@Configuration
|
|
|
@EnableWebSecurity
|
|
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
|
|
+@Log4j2
|
|
|
@Order(2)
|
|
|
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|
|
|
|
|
+ private final LoginAuthenticationSuccessHandler loginAuthenticationSuccessHandler;
|
|
|
+ private final LoginAuthenticationFailureHandler loginAuthenticationFailureHandler;
|
|
|
+ private final LogoutSuccessHandler logoutSuccessHandler;
|
|
|
+ private final UserRepository userRepository;
|
|
|
+
|
|
|
+ public WebSecurityConfig(LoginAuthenticationSuccessHandler loginAuthenticationSuccessHandler, LoginAuthenticationFailureHandler loginAuthenticationFailureHandler, LogoutSuccessHandler logoutSuccessHandler, UserRepository userRepository) {
|
|
|
+ this.loginAuthenticationSuccessHandler = loginAuthenticationSuccessHandler;
|
|
|
+ this.loginAuthenticationFailureHandler = loginAuthenticationFailureHandler;
|
|
|
+ this.logoutSuccessHandler = logoutSuccessHandler;
|
|
|
+ this.userRepository = userRepository;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
protected void configure(HttpSecurity http) throws Exception {
|
|
|
http.antMatcher("/**").authorizeRequests()
|
|
|
.antMatchers("/login**").permitAll()
|
|
|
- .antMatchers("/admin/**").hasAnyRole("ADMIN_SYSTEM", "ADMIN_BLOG")
|
|
|
+ .antMatchers("/admin/**").hasAnyRole("ADMIN")
|
|
|
+ // 其他地址的访问均放行
|
|
|
.anyRequest().permitAll()
|
|
|
+ .and().formLogin().loginPage("/login").loginProcessingUrl("/login")
|
|
|
+ // 用户名字段和密码字段
|
|
|
+ .usernameParameter("username").passwordParameter("password")
|
|
|
+ // 验证失败后跳转的请求
|
|
|
+ .failureUrl("/login?error=true")
|
|
|
+ .successHandler(loginAuthenticationSuccessHandler)
|
|
|
+ .failureHandler(loginAuthenticationFailureHandler)
|
|
|
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
|
|
|
- .logoutSuccessUrl("/logout")
|
|
|
+ .logoutSuccessUrl("/login?logout").logoutSuccessHandler(logoutSuccessHandler)
|
|
|
.and().csrf().disable();
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void configure(WebSecurity web) throws Exception {
|
|
|
+ web.ignoring().antMatchers(HttpMethod.GET, "/images/**", "/plugins/**");
|
|
|
+ web.ignoring().antMatchers(HttpMethod.GET, "/**/*.css");
|
|
|
+ web.ignoring().antMatchers(HttpMethod.GET, "/**/*.js");
|
|
|
+ web.ignoring().mvcMatchers(HttpMethod.GET, "/favicon.ico");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
|
+ auth.userDetailsService(new UserServiceImpl(userRepository)).passwordEncoder(new BCryptPasswordEncoder() {
|
|
|
+ @Override
|
|
|
+ public String encode(CharSequence rawPassword) {
|
|
|
+ log.info("密码加密 1 = {}", rawPassword);
|
|
|
+ log.info("密码加密 2 = {}", new BCryptPasswordEncoder().encode(rawPassword));
|
|
|
+ return new BCryptPasswordEncoder().encode(rawPassword);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
|
|
+ log.info("密码验证逻辑 3 = {}", rawPassword);
|
|
|
+ log.info("密码验证逻辑 4 = {}", encodedPassword);
|
|
|
+ log.info("密码验证逻辑 5 = {}", new BCryptPasswordEncoder().encode(rawPassword));
|
|
|
+ if (!encodedPassword.contentEquals(rawPassword)) {
|
|
|
+ throw new BadCredentialsException("密码错误!");
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|