주의
이 책은 Spring Security 5 버전을 기준으로 작성되었으므로, Spring Boot 3.X 버전에서는 일부 클래스가 더 이상 사용되지(deprecated) 않을 수 있습니다.
1. Matcher 메서드로 엔드포인트 선택
- 요청에 권한을 부여할 때 관리자 역할이 있는 사용자만 엔드포인트를 호출할 수 있도록 mvcMatchers() 메서드를 이용할 수 있음
- Matcher 메서드로 요청을 참조할 때는 특정한 규칙부터 일반적인 규칙의 순서로 지정해야 하므로 anyRequest() 메서드를 mvcMatchers() 같은 더 특정적인 Matcher 메서드보다 먼저 호출할 수 없음
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Configuration | |
public class ProjectConfig extends WebSecurityConfigurerAdapter { | |
@Override | |
@Bean | |
public UserDetailsService userDetailsService() { | |
var manager = new InMemoryUserDetailsManager(); | |
var user1 = User.withUsername("john") | |
.password("12345") | |
.roles("ADMIN") | |
.build(); | |
var user2 = User.withUsername("jane") | |
.password("12345") | |
.roles("MANAGER") | |
.build(); | |
manager.createUser(user1); | |
manager.createUser(user2); | |
return manager; | |
} | |
@Bean | |
public PasswordEncoder passwordEncoder() { | |
return NoOpPasswordEncoder.getInstance(); | |
} | |
@Override | |
protected void configure(HttpSecurity http) throws Exception { | |
http.httpBasic(); | |
http.authorizeRequests() | |
.mvcMatchers("/hello").hasRole("ADMIN") // 관리자 역할인 사용자만 /hello 엔드포인트 호출 가능 | |
.mvcMatchers("/ciao").hasRole("MANAGER") // 운영자 역할인 사용자만 /ciao 엔드포인트 호출 가능 | |
.anyRequest().permitAll(); // 나머지 모든 엔드포인트에 대해 모든 요청 허용 | |
//.anyRequest().denyAll(); | |
//.anyRequest().authenticated(); | |
} | |
} |
2. MVC Matcher 메서드로 권한을 부여할 요청 선택
- 권한 부여 구성을 적용할 요청을 지정하는 일반적인 방법은 MVC 식을 이용하는 것
- MVC Matcher 메서드는 표준 MVC 구문으로 경로를 지정하며 해당 구문은 @RequestMapping, @GetMapping, @PostMapping 등의 어노테이션으로 엔드포인트 매핑을 작성할 때의 구문과 동일함
- 다음 두 메서드로 MVC Matcher 메서드를 선언할 수 있음
- mvcMatchers(HttpMethod method, String... patterns): 제한을 적용할 HTTP 방식과 경로를 모두 지정할 수 있으며 같은 경로에 대해 HTTP 방식별로 다른 제한을 적용할 때 유용함
- mvcMatchers(String... patterns): 경로만을 기준으로 권한 부여 제한을 적용할 때 간단하게 이용 가능, 해당 메서드를 이용하면 자동으로 해당 경로의 모든 HTTP 방식에 제한이 적용됨
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Configuration | |
public class ProjectConfig extends WebSecurityConfigurerAdapter { | |
@Override | |
@Bean | |
public UserDetailsService userDetailsService() { | |
var manager = new InMemoryUserDetailsManager(); | |
var user1 = User.withUsername("john") | |
.password("12345") | |
.roles("ADMIN") | |
.build(); | |
var user2 = User.withUsername("bill") | |
.password("12345") | |
.roles("MANAGER") | |
.build(); | |
manager.createUser(user1); | |
manager.createUser(user2); | |
return manager; | |
} | |
@Bean | |
public PasswordEncoder passwordEncoder() { | |
return NoOpPasswordEncoder.getInstance(); | |
} | |
@Override | |
protected void configure(HttpSecurity http) throws Exception { | |
http.httpBasic(); | |
http.authorizeRequests() | |
// HTTP GET 방식으로 /a 경로를 요청하면 앱이 사용자를 인증해야 함 | |
.mvcMatchers(HttpMethod.GET, "/a").authenticated() | |
// HTTP POST 방식으로 /a 경로를 요청하면 모두 허용 | |
.mvcMatchers(HttpMethod.POST, "/a").permitAll() | |
// 다른 경로에 대한 모든 요청 거부 | |
.anyRequest().denyAll(); | |
// HTTP Post 방식으로 /a 경로를 호출할 수 있게 CSRF 비활성화 | |
http.csrf().disable(); | |
} | |
} |
- 여러 경로에 같은 권한 부여 규칙을 적용하는 방법은 크게 두 가지가 있음
- 권한 부여 규칙을 적용할 경로를 모두 열거하는 방법: 경로가 많아질 경우 코드가 장황해짐
- 경로 식을 통해 같은 접두사로 시작하는 경로 그룹에는 항상 같은 권한 부여 규칙을 적용: 같은 그룹에 새 경로를 추가할 때는 권한 부여 구성을 변경할 필요가 없다는 장점이 있음
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Configuration | |
public class ProjectConfig extends WebSecurityConfigurerAdapter { | |
@Override | |
@Bean | |
public UserDetailsService userDetailsService() { | |
var manager = new InMemoryUserDetailsManager(); | |
var user1 = User.withUsername("john") | |
.password("12345") | |
.roles("ADMIN") | |
.build(); | |
var user2 = User.withUsername("jane") | |
.password("12345") | |
.roles("MANAGER") | |
.build(); | |
manager.createUser(user1); | |
manager.createUser(user2); | |
return manager; | |
} | |
@Bean | |
public PasswordEncoder passwordEncoder() { | |
return NoOpPasswordEncoder.getInstance(); | |
} | |
@Override | |
protected void configure(HttpSecurity http) throws Exception { | |
http.httpBasic(); | |
http.authorizeRequests() | |
// /a/b/** 식은 접두사 /a/b가 붙은 모든 경로를 나타냄 | |
.mvcMatchers( "/a/b/**").authenticated() | |
.anyRequest().permitAll(); | |
http.csrf().disable(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Configuration | |
public class ProjectConfig extends WebSecurityConfigurerAdapter { | |
@Override | |
protected void configure(HttpSecurity http) throws Exception { | |
http.httpBasic(); | |
http.authorizeRequests() | |
// 길이와 관계없이 숫자를 포함하는 문자열을 나타내는 정규식 | |
.mvcMatchers( "/product/{code:^[0-9]*$}").permitAll() | |
.anyRequest().denyAll(); | |
} | |
} |
MVC Matcher 메서드에 사용하는 식 | 설명 |
/a | /a 경로만 |
/a/* | * 연산자는 한 경로 이름만 대체 이 경우 /a/b 또는 /a/c와는 일치하지만, /a/b/c와는 일치하지 않음 |
/a/** | ** 연산자는 여러 경로 일므을 대체 이 경우 /a, /a/b, /a/b/c가 모두 이 식과 일치함 |
/a/{param} | 이 식은 주어진 경로 매개변수를 포함한 /a 경로에 적용 |
/a/{param:regex} | 이 식은 매개변수 값과 주어진 정규식이 일치할 때만 주어진 경로 매개변수를 포함한 /a 경로에 적용됨 |
3. Ant Matcher로 권한을 부여할 요청 선택
- Ant Matcher는 다음의 세 메서드를 이용함
- antMatchers(HttpMethod method, String patterns): 제한을 적용할 HTTP 방식과 경로를 참조할 앤트 패턴을 모두 지정 가능, 같은 경로 그룹에 대해 HTTP 방식별로 다른 제한을 적용할 때 유용함
- antMatchers(String patterns): 경로만을 기준으로 권한 부여 제한을 적용할 때 더 쉽고 간단하게 이용할 수 있음, 모든 HTTP 방식에 자동으로 제한이 적용됨
- antMatchers(HttpMethod method): antMatchers(httpMethod, "/**")와 같은 의미이며 경로와 관계없이 특정 HTTP 방식을 지정할 수 있음
- Ant Matcher는 패턴에 대해 주어진 앤트 식을 그대로 적용하며 스프링의 미묘한 MVC 기능은 고려하지 않음
- 이 경우 /hello는 /hello/ 경로에 앤트 식으로 적용되지 않음
- /hello/ 경로도 보호하려면 이를 개별적으로 추가하거나 일치하는 앤트 식을 작성해야 함
- Ant Matcher보다는 MVC Matcher를 이용하는 것을 권장
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
protected void configure(HttpSecurity http) throws Exception { | |
http.httpBasic(); | |
http.authorizeRequests() | |
.antMatchers( "/hello").authenticated(); | |
} |
4. Regex Matcher로 권한을 부여할 요청 선택
- 정규식은 어떤 문자열 형식이든지 나타낼 수 있으므로 무한의 가능성을 제공하지만 간단한 시나리오에 적용하더라도 읽기 어렵다는 단점이 있음
- 따라서 MVC나 Ant Matcher를 우선적으로 이용하고 다른 대안이 없을 때만 정규식을 이용하는 것을 권장
- 다음 두 메서드로 Regex Matcher를 구현할 수 있음
- regexMatchers(HttpMethod method, String regex): 제한을 적용할 HTTP 방식과 경로를 참조할 정규식을 모두 지정함, 같은 경로 그룹에 대해 HTTP 방식별로 다른 제한을 적용할 때 유용함
- regexMatchers(String regex): 경로만을 기준으로 권한 부여 제한을 적용할 때 더 쉽고 간단하게 이용할 수 있음, 모든 HTTP 방식에 자동으로 제한이 적용됨
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Configuration | |
public class ProjectConfig extends WebSecurityConfigurerAdapter { | |
@Override | |
@Bean | |
public UserDetailsService userDetailsService() { | |
var uds = new InMemoryUserDetailsManager(); | |
var u1 = User.withUsername("john") | |
.password("12345") | |
.authorities("read") | |
.build(); | |
var u2 = User.withUsername("jane") | |
.password("12345") | |
.authorities("read", "premium") | |
.build(); | |
uds.createUser(u1); | |
uds.createUser(u2); | |
return uds; | |
} | |
@Bean | |
public PasswordEncoder passwordEncoder() { | |
return NoOpPasswordEncoder.getInstance(); | |
} | |
@Override | |
protected void configure(HttpSecurity http) throws Exception { | |
http.httpBasic(); | |
http.authorizeRequests() | |
// 사용자 인증을 위한 경로의 조건으로 정규식을 이용 | |
.regexMatchers(".*/(us|uk|ca)+/(en|fr).*") | |
.authenticated() | |
// 사용자가 프리미엄 액세스를 이용하는 데 필요한 다른 경로 구성 | |
.anyRequest().hasAuthority("premium"); | |
} | |
} |
참고
스프링 시큐리티 인 액션
반응형
'Spring > 스프링 시큐리티 인 액션' 카테고리의 다른 글
[12장] OAuth 2가 작동하는 방법 (0) | 2025.05.31 |
---|---|
[10장] CSRF 보호와 CORS 적용 (0) | 2025.05.31 |
[7장] 권한 부여 구성: 액세스 제한 (0) | 2025.05.30 |
[5장] 인증 구현 (0) | 2025.05.21 |
[4장] 암호 처리 (0) | 2025.05.19 |