Spring Security 내용 정리
해당 포스트는 Security를 공부하면서 내용을 정리하는 포스트 이다.
1. @EnableWebSecurity
- 해당 어노테이션은 스프링 시큐리티를 활성화 하고 웹보안 설정을 구성하는데 사용된다고한다.
-> spring Security 사용할거면 클래스의 상단에 @EnableWebSecurity를 선언해주자
하단의 내용의 경우 5.7 이전 버전의 내용이다.
=> 경우 extends를 통해 webSecurityConfigurerAdapter를 상속받아 오버라이딩하는 방식이다.
@EnableWebSecurity // SecurityConfig로 시큐리티를 제어함.
public class SecurityConfig {
// ...
}
하단의 내용은 6.x 버전부터의 내용이다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// ...
}
=> 경우 extends를 통해 webSecurityConfigurerAdapter를 상속받아 사용하는 방식이 사라졌다.
- 바로아래 참고 블로그 링크를 남겨두었다
[Spring Security] 스프링 시큐리티 기초
** 스프링부트를 기준으로 작성되었습니다** 0. 스프링 시큐리티의 동작과 구조 스프링 시큐리티를 구현하기에 앞서 스프링 시큐리티가 동작하는 방식에 대해서 이해하면 시큐리티에 대해 더 깊
myvelop.tistory.com
하단은 Spring Security 6.x 버전의 내용
- 바로 아래 공식사이트 링크를 남겨두었다
Configuration Migrations :: Spring Security
In 6.0, @Configuration is removed from @EnableWebSecurity, @EnableMethodSecurity, @EnableGlobalMethodSecurity, and @EnableGlobalAuthentication. To prepare for this, wherever you are using one of these annotations, you may need to add @Configuration. For ex
docs.spring.io
Security 5.8에서 새로운 메소드가 추가되고
6.x버전에서는 이제 권장되지 않는 메소드는 메소드가 삭제되었다고 한다
삭제된 메소드
- antMatchers()
- mvcMatchers()
- regexMatchers()
대체 메소드
- requestMatchers()
6.1 버전 관련된 포스트가 있어 링크 걸어둔다 한번쯤 쓱 훑어 보는것이 좋을것같다.
Spring Security) Spring Boot 3.1.0, Spring 6.1, Spring Security 6.1
Springboot 3.1.0 환경에서 Spring Security로 인증 방식을 구현하던 중 FilterChain 등록 코드에서 deprecated 에러 사인이 등장했다. Spring Security 6.1.0 SpringBoot 3.1.0 버전은 Spring Security 6.1.0 버전을 dependency 한다.
byungil.tistory.com
공식 사이트에서 참고 예제를 올려 놓은 부분을 올려 둘테니 확인해보자
security를 맨땅에 헤딩을 하다보니
정확히 어떤동작을 하고 모르는 내용이 잔뜩 있으니 나중에 해당 내용의 상세 내용을 수정해야겠다.
webSecurityConfigurerAdapter 의 삭제로 인한 변경된 내용
- SecurityFilterChain @Bean 게시
- WebSecurityCustomizer @Bean 게시
- AuthenticationManager @Bean 게시
- JDBC 인증방법변경 - AuthenticationManagerBuilder .jdbcAuthentication 사용
- 메모리 내 인증방법 변경 - AuthenticationManagerBuilder.inMemoryAuthentication 사용
-> JDBC 인증방법과 메모리내 인증방법의 경우 정리해두진 않았다 공식 사이트를 참조하자
- SecurityFilterChain @Bean 게시
삭제 이전버전
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
}
}
삭제 후 버전 (6.x)
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
return http.build();
}
}
- WebSecurityCustomizer @Bean 게시
삭제 이전버전
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/ignore1", "/ignore2");
}
}
삭제 후 버전 (6.x)
@Configuration
public class SecurityConfiguration {
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
}
}
- AuthenticationManager @Bean 게시
삭제 이전버전
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDetailsContextMapper(new PersonContextMapper())
.userDnPatterns("uid={0},ou=people")
.contextSource()
.port(0);
}
}
삭제 후 버전 (6.x)
@Configuration
public class SecurityConfiguration {
@Bean
public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
contextSourceFactoryBean.setPort(0);
return contextSourceFactoryBean;
}
@Bean
AuthenticationManager ldapAuthenticationManager(BaseLdapPathContextSource contextSource) {
LdapBindAuthenticationManagerFactory factory =
new LdapBindAuthenticationManagerFactory(contextSource);
factory.setUserDnPatterns("uid={0},ou=people");
factory.setUserDetailsContextMapper(new PersonContextMapper());
return factory.createAuthenticationManager();
}
}
SecurityFilterChain의 내용
- 기초 내용변경 예제
- 클래스 경로에 Spring MVC가 있고 메소드를 사용하는 경우
- servletPath의 속성을 사용자 정의하는 경우 - 정리 하지않음 공식문서 참조하자
- requestMatchers 문제 시 requestMatchers()으로 다시 antMatcher()으로 변경하는 경우
- CSRF 구성을 사용자 정의하는 경우
- HttpSecurity의 matcher() -> securityMatcher()으로 변경됨
- HttpSecurity의 RequestMatcher()구성에서 사용자 정의를 사용 (단일건, 다중건)의 경우
- securityMatchers() 문제 시 requestMatcher()로 antMatcher()으로 변경하는경우
5.7버전
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/user/**").hasRole("USER")
.anyRequest().authenticated()
);
return http.build();
}
}
6.1 버전
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/user/**").hasRole("USER")
.anyRequest().authenticated()
);
return http.build();
}
}
코드상으로 antMatchers -> requestMatchers로 대체 되었다.
- 클래스 경로에 Spring MVC가 있고 메소드를 사용하는 경우
5.7버전
@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.mvcMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}
6.1 버전
@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}
코드상에선 @EnableWebMvc 어노테이션을 클래스 상단에 선언해주면 6.1이전의 mvcMatchers()의 기능을 대체하여 동작하는듯하다.
- servletPath의 속성을 사용자 정의하는 경우도 있지만 공식 자료를 참고하자
- requestMatchers 문제 시 requestMatchers()으로 다시 antMatcher()으로 변경하는 경우
-> 새로운 메소드에 문제가 있는경우 언제든 사용중이던 requestMatchers으로 다시 전환 할 수 있다고한다.
해당내용의 코드는 하단에 예제를 참고하자
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
import static org.springframework.security.web.util.matcher.RegexRequestMatcher.regexMatcher;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.requestMatchers(AntPathRequestMatcher.antMatcher("/user/**")).hasRole("USER")
.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/user/**")).hasRole("ADMIN")
.requestMatchers(RegexRequestMatcher.regexMatcher(".*\\?x=y")).hasRole("SPECIAL") // matches /any/path?x=y
.anyRequest().authenticated()
);
return http.build();
}
}
코드상으로 봤을때 requsetMatchers의 파라미터 부분에서 antMatcher, regexMatcher를 선언할수 있는듯하다.
- regexMatcher의 경우 정규식을 통한 방법이라고한다.
위의 내용으로 구현할 수있는 리스트는 아래의 내용과 같다.
- 공식문서에서의 내용만 보고 작성한것으로 하단 말고 추가적으로 더 가능한지는 나중에 확인해 봐야겠다
- AntPathRequestMatcher
- RegexRequestMatcher
- CSRF 구성을 사용자 정의하는 경우
5.7버전
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf((csrf) -> csrf
.ignoringAntMatchers("/no-csrf")
);
return http.build();
}
6.1 버전
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf((csrf) -> csrf
.ignoringRequestMatchers("/no-csrf")
);
return http.build();
}
- HttpSecurity의 matcher 사용법 변경 -> securityMatcher
5.7버전
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**", "/app/**")
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
5.8버전
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityMatcher("/api/**", "/app/**")
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
5.8부터는 HttpSecurity의 antMatchers(), mvcMatchers() 및 requestMatchers() 메소드가 더 이상 사용되지 않습니다.
대신 securityMatcher()가 추가되었다고 한다.
-> 혼동을 피하기 위해서라나?
- HttpSecurity의 RequestMatcher구성에서 사용자 정의를 사용하는 경우 ->
- 단일건, 다중건
단일건 5.7버전
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.requestMatcher(new MyCustomRequestMatcher())
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
public class MyCustomRequestMatcher implements RequestMatcher {
// ...
}
단일건 5.8버전
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityMatcher(new MyCustomRequestMatcher())
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
public class MyCustomRequestMatcher implements RequestMatcher {
// ...
}
단일건의 경우
해당 내용은 securityMatcher()를 사용해 사용자 정의를 사용하는경우 인데
requestMatcher() -> securityMatcher() 로 바뀐것 말곤 차이가 없는듯하다.
다중건 5.7버전
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.requestMatchers((matchers) -> matchers
.antMatchers("/api/**", "/app/**")
.mvcMatchers("/admin/**")
.requestMatchers(new MyCustomRequestMatcher())
)
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
다중건 5.8버전
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityMatchers((matchers) -> matchers
.requestMatchers("/api/**", "/app/**", "/admin/**")
.requestMatchers(new MyCustomRequestMatcher())
)
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
다중건의 경우 단일건과 차이를 정리한 리스트는 아래 있다.
- 단일건 : securityMatcher
- 다중건 : securityMatchers
- 다중건의 경우 securityMatchers를 람다표현식을 통해 다중으로 구현
- securityMatchers() 문제 시 requestMatcher()로 antMatcher()으로 변경하는경우
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityMatchers((matchers) -> matchers
.requestMatchers(AntPathRequestMatcher.antMatcher("/api/**")
, AntPathRequestMatcher.antMatcher("/app/**"))
)
.authorizeHttpRequests((authz) -> authz
.requestMatchers(AntPathRequestMatcher.antMatcher("/api/admin/**")).hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
WebSecurityCustomizer
5.7버전
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
}
6.1 버전
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/ignore1", "/ignore2");
}
antMatchers -> requestMatchers로 변경
'Spring_Securtiy > 에러해결 및 참조사항정리' 카테고리의 다른 글
Spring Security + oauth2.0 무한 리다이렉션 문제 해결 (0) | 2023.11.15 |
---|---|
Spring Security 사용방법 및 메소드 설명 블로그 - v5.8 이전기준 (0) | 2023.11.11 |
Spring Security 간단 사용방법 예제 - v5.8 이전기준 (0) | 2023.11.10 |
Spring Security 동작 구조 (0) | 2023.11.10 |