JAVA
자바 스프링부트 2.7.7->3.3.9 업그레이드 (2)
생활개발
2025. 3. 5. 09:41
728x90
1편 바로가기 : 자바 스프링부트 2.7.7->3.3.9 업그레이드 (1)
1편에는 기본셋팅 gradle만 설정했었는데
이번엔 스프링시큐리티가 6버전으로 바뀌면서 오류 투성이!
기존)
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
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.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.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.session.HttpSessionEventPublisher;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Autowired
SecurityDAO securitydao;
@Autowired
private LoginIdPwValidator userDetailService;
@Value("${spring.config.activate.on-profile}")
private String env;
/* Session 관리 */
@Bean
SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
/* SuccessHandler */
@Bean
LoginSuccessHandler loginSuccessHandler() { return new LoginSuccessHandler(); }
/* FailureHandler */
@Bean
LoginFailureHandler loginFailureHandler() { return new LoginFailureHandler(); }
/* HttpSession 이벤트를 Spring 이벤트로 변환, 세션 생성 및 소멸 이벤트를 처리하는 데 도움이 된다. */
@Bean
public ServletListenerRegistrationBean<HttpSessionEventPublisher> httpSessionEventPublisher() {
return new ServletListenerRegistrationBean<HttpSessionEventPublisher>(new HttpSessionEventPublisher());
}
/* 아이디/비밀번호 exception 구분의 위함 */
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
DaoAuthenticationProvider bean = new DaoAuthenticationProvider();
bean.setHideUserNotFoundExceptions(false); //기본으로 true로 지정, false 지정시 UsernameNotFoundException 사용 가능
bean.setUserDetailsService(userDetailService); //필수값
bean.setPasswordEncoder(passwordEncoder()); //필수값
return bean;
}
// 스프링시큐리티 표준 BCrypt 암호화 사용
// 비밀번호 암호화 암호를 해제시키는 경우 BCryptPasswordEncoder를 사용한다.
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/*@Bean
public PasswordEncoder getPasswordEncoder(){
return new BCryptPasswordEncoder();
}*/
/*
* 인증예외처리 : 스프링 시큐리티 룰을 무시하게 하는 URL 규칙
* */
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**", "/img/**", "/vendor/**","/fonts/**");
web.ignoring().antMatchers("/admin/find_idpw_proc", "/admin/find_idpw", "/admin/pw_mail", "/admin/reset_pw", "/admin/find_idpw_proc",
"/admin/reset_pw_proc", "/admin/stat/chkVisitors_proc", "/admin/stat/chkUrlVisitors_proc");
}
/*
* 설정 : 스프링 시큐리티 규칙
* */
@Override
protected void configure(HttpSecurity http) throws Exception{
http
.csrf().disable() //비활성. 적용시에는 POST, 토큰값 필수
.antMatcher("/admin/**") //뒤로갈수록 넓은 범위
.authorizeRequests() //요청에 의한 보안검사 시작
// .antMatchers("/admin/newsletter_upload").authenticated() //로그인 해야 접속가능
.antMatchers("/admin/**").authenticated() //admin 폴더 전부 로그인 해야 접속가능
.anyRequest().authenticated() //MASTER, MAIN 권한만 접속 가능
.and()
.formLogin() //보안 검증은 formLogin방식으로 하겠다.
.loginPage("/admin/login")//사용자 정의 로그인 페이지
.usernameParameter("username")//아이디 파라미터명 설정 : login Form에서 input 아이디 name이 username 이어야 인식 됨
.passwordParameter("password")//패스워드 파라미터명 설정 : login Form에서 input 패스워드 name이 password 이어야 인식 됨
.successHandler(loginSuccessHandler())
.loginProcessingUrl("/admin/loginProc")//로그인 Form Action Url
.permitAll() //로그인 페이지는 모두 접근 허용
.failureHandler(loginFailureHandler())
.and()
.logout()
.logoutUrl("/admin/logout") //로그아웃 url
.logoutSuccessUrl("/admin/login")
.invalidateHttpSession(true)
.and()
.sessionManagement()
.maximumSessions(-1)
.sessionRegistry(sessionRegistry())
;
}
}
WebSecurityConfigurerAdapter가 5.7버전부터인가 없어졌다고함!
그래서 수정중..
configure 2개를 바꿔야하는데
먼저 HttpSecurity http 이부분부터!
변경전)
@Override
protected void configure(HttpSecurity http) throws Exception{
http
.csrf().disable() //비활성. 적용시에는 POST, 토큰값 필수
.antMatcher("/admin/**") //뒤로갈수록 넓은 범위
.authorizeRequests() //요청에 의한 보안검사 시작
// .antMatchers("/admin/newsletter_upload").authenticated() //로그인 해야 접속가능
.antMatchers("/admin/**").authenticated() //admin 폴더 전부 로그인 해야 접속가능
.anyRequest().authenticated() //MASTER, MAIN 권한만 접속 가능
.and()
.formLogin() //보안 검증은 formLogin방식으로 하겠다.
.loginPage("/admin/login")//사용자 정의 로그인 페이지
.usernameParameter("username")//아이디 파라미터명 설정 : login Form에서 input 아이디 name이 username 이어야 인식 됨
.passwordParameter("password")//패스워드 파라미터명 설정 : login Form에서 input 패스워드 name이 password 이어야 인식 됨
.successHandler(loginSuccessHandler())
.loginProcessingUrl("/admin/loginProc")//로그인 Form Action Url
.permitAll() //로그인 페이지는 모두 접근 허용
.failureHandler(loginFailureHandler())
.and()
.logout()
.logoutUrl("/admin/logout") //로그아웃 url
.logoutSuccessUrl("/admin/login")
.invalidateHttpSession(true)
.and()
.sessionManagement()
.maximumSessions(-1)
.sessionRegistry(sessionRegistry())
;
}
변경후)
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) //비활성. 적용시에는 POST, 토큰값 필수
//권한 설정
.authorizeHttpRequests(request -> request //요청에 의한 보안검사 시작
.requestMatchers("/admin/**").authenticated() //admin 폴더 전부 로그인 해야 접속가능
.anyRequest().permitAll() // 그 외 모든 요청은 인증 없이 접근 가능
)
//로그인 설정
.formLogin(login -> login //보안 검증은 formLogin방식으로 하겠다.
.loginPage("/admin/login")//사용자 정의 로그인 페이지
.loginProcessingUrl("/admin/loginProc")//로그인 Form Action Url
.usernameParameter("username")//아이디 파라미터명 설정 : login Form에서 input 아이디 name이 username 이어야 인식 됨
.passwordParameter("password")//패스워드 파라미터명 설정 : login Form에서 input 패스워드 name이 password 이어야 인식 됨
.successHandler(loginSuccessHandler()) //로그인 성공 로직
.failureHandler(loginFailureHandler()) //로그인 실패 로직
.permitAll() //로그인 페이지는 모두 접근 허용
)
//로그아웃 설정
.logout(logout -> logout
.logoutUrl("/admin/logout") //로그아웃 url
.logoutSuccessUrl("/admin/login") //로그아웃 성공 후 이동할 url
.invalidateHttpSession(true) //세션 무효화 로그아웃 후 세션 모두 삭제
)
//세션 관리 설정
.sessionManagement(session -> session //세션 관리 기능 활성화
.maximumSessions(-1) //최대 허용 세선 수 -1이면 무제한
.sessionRegistry(sessionRegistry()) //활성화 된 세션 정보를 관리
)
;
return http.build();
}
어노테이션부터 @Override -> @Bean으로 변경
상속받아오는 configure가 없어지면서 수정됨
csrf 비활성화)
//변경전
.csrf().disable()
//변경후
.csrf(csrf -> csrf.disable())
개인적으로 이거 찾는게 제일 힘들었음.
기존 .and()하는 체이닝 하는 방식에서 람다표현식으로 변경
그리고 스프링스큐리티 5->6으로 변경하면서 함수들도 많이 바뀌었음.
authorizeRequests() → authorizeHttpRequests()
antMatchers(), antMatcher() -> requestMatchers()
이렇게 2개 함수가 바뀌어 수정
인증)
//변경전
.antMatcher("/admin/**") //뒤로갈수록 넓은 범위
.authorizeRequests() //요청에 의한 보안검사 시작
.antMatchers("/admin/**").authenticated() //admin 폴더 전부 로그인 해야 접속가능
.anyRequest().authenticated() //MASTER, MAIN 권한만 접속 가능
//변경후
.authorizeHttpRequests(request -> request //요청에 의한 보안검사 시작
.requestMatchers("/admin/**").authenticated() //admin 폴더 전부 로그인 해야 접속가능
.anyRequest().permitAll() // 그 외 모든 요청은 인증 없이 접근 가능
)
그 외 로그인, 로그아웃, 세션관리 하는 부분은 다행히 크게 달리진 부분없이
표현식만 바뀌어서 수정!
로그인, 로그아웃, 세션)
//변경전
.and()
.formLogin() //보안 검증은 formLogin방식으로 하겠다.
.loginPage("/admin/login")//사용자 정의 로그인 페이지
.usernameParameter("username")//아이디 파라미터명 설정 : login Form에서 input 아이디 name이 username 이어야 인식 됨
.passwordParameter("password")//패스워드 파라미터명 설정 : login Form에서 input 패스워드 name이 password 이어야 인식 됨
.successHandler(loginSuccessHandler())
.loginProcessingUrl("/admin/loginProc")//로그인 Form Action Url
.permitAll() //로그인 페이지는 모두 접근 허용
.failureHandler(loginFailureHandler())
.and()
.logout()
.logoutUrl("/admin/logout") //로그아웃 url
.logoutSuccessUrl("/admin/login")
.invalidateHttpSession(true)
.and()
.sessionManagement()
.maximumSessions(-1)
.sessionRegistry(sessionRegistry())
//변경후
//로그인 설정
.formLogin(login -> login //보안 검증은 formLogin방식으로 하겠다.
.loginPage("/admin/login")//사용자 정의 로그인 페이지
.loginProcessingUrl("/admin/loginProc")//로그인 Form Action Url
.usernameParameter("username")//아이디 파라미터명 설정 : login Form에서 input 아이디 name이 username 이어야 인식 됨
.passwordParameter("password")//패스워드 파라미터명 설정 : login Form에서 input 패스워드 name이 password 이어야 인식 됨
.successHandler(loginSuccessHandler()) //로그인 성공 로직
.failureHandler(loginFailureHandler()) //로그인 실패 로직
.permitAll() //로그인 페이지는 모두 접근 허용
)
//로그아웃 설정
.logout(logout -> logout
.logoutUrl("/admin/logout") //로그아웃 url
.logoutSuccessUrl("/admin/login") //로그아웃 성공 후 이동할 url
.invalidateHttpSession(true) //세션 무효화 로그아웃 후 세션 모두 삭제
)
//세션 관리 설정
.sessionManagement(session -> session //세션 관리 기능 활성화
.maximumSessions(-1) //최대 허용 세선 수 -1이면 무제한
.sessionRegistry(sessionRegistry()) //활성화 된 세션 정보를 관리
)
이렇게보면 너~~~무 간단해 보이는데
이거 하는데만 1주일정도 걸렸다...
챗gpt쓰면서 하면 금방 하겠지~~ 했는데
얘도 잘 모르는거같았음
또 타임리프랑 컨트롤러쪽 수정하고 있는데 아마 3편에서 마무리할 것같습니다!
728x90