Spring security 5.7.X버전 부턴 SecurityConfig 클래스에
WebSecurityConfigurerAdapter 를 상속받아 Configure()로 사용하는게 불가능해짐
따라서 @Bean방식으로 사용해야함
@Bean
public InMemoryUserDetailsManager user() {
UserDetails user = User.withUsername("user1")
//비밀번호 1111 Encode함
.password("$2a$10$yxmlE1fKRduWxvTqrThx4OByZeY9ZUxdTRoloNn262TkcfAbotyke")
.roles("USER").build();
return new InMemoryUserDetailsManager(user);
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/sample/all").permitAll()
.antMatchers("/sample/member").hasRole("USER");
http.formLogin();
return http.build();
}
IntellJ IDE에서
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
코드를 사용하면 (HttpSecurity http)
에서 자동 주입을 할 수 없습니다. 'HttpSecurity' 타입의 bean을 찾을 수 없습니다.
라는 오류가 발생함
해결완료
package com.crow.oauthex.config;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@Log4j2
@EnableWebSecurity
public class SecurityConfig {
/* @Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring()
.mvcMatchers("/node_modules/**")
.requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}*/
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/* @Bean
public InMemoryUserDetailsManager user() {
UserDetails user = User.withUsername("user1")
//비밀번호 1111 Encode함
.password("$2a$10$yxmlE1fKRduWxvTqrThx4OByZeY9ZUxdTRoloNn262TkcfAbotyke")
.roles("USER").build();
return new InMemoryUserDetailsManager(user);
}*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/sample/all").permitAll()
.antMatchers("/sample/member").hasRole("USER");
http.formLogin();
http.csrf().disable();
http.logout();
return http.build();
}
}
위 코드처럼 @EnableWebSecurity
어노테이션을 클래스에 선언해주면 'HttpSecurity' 타입의 bean을 찾을 수 없습니다. 오류 해결 가능함
위의 내용은 그냥 spring.io를 보면 당연히 알수있는 내용이었다
중요한건 AuthenticationManager 이 인터페이스를 사용하는
인증 부분이다.
이 부분을
package com.github.studym.studymarathon.config;
import com.github.studym.studymarathon.config.security.filter.ApiCheckFilter;
import com.github.studym.studymarathon.config.security.filter.ApiLoginFilter;
import com.github.studym.studymarathon.config.security.handler.ApiLoginFailHandler;
import com.github.studym.studymarathon.config.security.handler.MemberLoginSuccessHandler;
import com.github.studym.studymarathon.config.security.service.AuthUserDetailsService;
import com.github.studym.studymarathon.config.security.util.JWTUtil;
import lombok.extern.log4j.Log4j2;
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.annotation.authentication.configuration.AuthenticationConfiguration;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@Log4j2
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig {
@Autowired
private AuthUserDetailsService userDetailsService;
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
/* http.authorizeRequests().antMatchers("/api/title").permitAll();
http.authorizeRequests().antMatchers("/api/main").hasRole("USER");
http.authorizeRequests().antMatchers("api/admin").hasRole("ADMIN");*/
http.formLogin();
http.csrf().disable();
http.logout();
http.oauth2Login().successHandler(successHandler());
http.rememberMe().tokenValiditySeconds(60 * 10).userDetailsService(userDetailsService);//10분짜리 로그인 유지 토큰
AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
http.addFilterBefore(apiCheckFilter(), UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(apiLoginFilter(authenticationManager), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public MemberLoginSuccessHandler successHandler() {
return new MemberLoginSuccessHandler(passwordEncoder());
}
@Bean
public ApiLoginFilter apiLoginFilter(AuthenticationManager authenticationManager) throws Exception {
ApiLoginFilter apiLoginFilter = new ApiLoginFilter("/api/login", jwtUtil());
apiLoginFilter.setAuthenticationManager(authenticationManager);
apiLoginFilter.setAuthenticationFailureHandler(new ApiLoginFailHandler());
return apiLoginFilter;
}
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
}
SecurityFilterChain() 메서드의 안에 선언하고
HttpSecurity를 이용해서 getSharedObject를 통해 얻어옴
http.getSharedObject(AuthenticationManager.class);
참조
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter