스프링시큐리티 인액션 8장
http.authorizeRequests()
.mvcMatchers("/hello").hasRole("ADMIN")
.mvcMatchers("/ciao").hasRole("MANAGER")
.anyRequest().permitAll();
.authorizeRequests()
.antMatchers("/css/**", "/assets/**", "/favicon/**", "/fonts/**", "/images/**", "/js/**", "/lib/**", "/favicon.ico").permitAll()
antMatchers vs mvcMatchers
mvcMatchers는 처음 봐서 찾아봄.
https://velog.io/@topy/antMatchers-vs-mvcMatchers
antMatchers vs mvcMatchers
antMatchers vs mvcMatchers
velog.io
- antMatchers("/test")는 정확한 /test URL만 일치.
- mvcMatchers("/test")는 /test, /test/, /test.html, /test.xyz 등 다양하게 일치
위의 결과가 바로 antMatchers의 단점이다.
antMatchers는 url 뒤에 /가 붙어있으면 이것을 인식하지 못한다.
그 이유는 REST 아키텍처 규칙상 URI 끝에는 슬래시(/)가 붙지 않아야 하므로, ‘/test/’ URI 요청을 ‘/test’로 인식해버려 접근을 허용하기 때문이다.
스프링시큐리티 3에서는 requestMatchers를 사용.
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final ProgramMngDao programDao;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
.requestMatchers("js/**", "css/**", "lib/**").permitAll()
@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")
.mvcMatchers("/ciao").hasRole("MANAGER")
.anyRequest().permitAll();
//.anyRequest().denyAll();
//.anyRequest().authenticated();
}
C:\Users\user>curl http://localhost:8080/hola --user "john:12345"
Hola!
C:\Users\user>curl http://localhost:8080/hello --user "john:12345"
Hello!
C:\Users\user>curl http://localhost:8080/ciao --user "john:12345"
{"timestamp":"2023-08-04T02:03:25.971+00:00","status":403,"error":"Forbidden","message":"","path":"/ciao"}
그 이외의 모든 리퀘스트는 허용할 경우라도
.anyRequest().permitAll();
잘못된 사용자로 접근하면 에러남
C:\Users\user>curl http://localhost:8080/hola --user "john:12345xxx"
{"timestamp":"2023-08-04T02:04:32.732+00:00","status":401,"error":"Unauthorized","message":"","path":"/hola"}
C:\Users\user>curl http://localhost:8080/hola
Hola!
.anyRequest().authenticated();
인증된 사용자만 접근가능.
HttpMethod.GET는 처음 알음...
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic();
http.authorizeRequests()
.mvcMatchers(HttpMethod.GET, "/a").authenticated()
.mvcMatchers(HttpMethod.POST, "/a").permitAll()
.anyRequest().denyAll();
http.csrf().disable();
}
컨트롤러 소스
@RestController
public class TestController {
@PostMapping("/a")
public String postEndpointA() {
return "Works!";
}
@GetMapping("/a")
public String getEndpointA() {
return "Works!";
}
@GetMapping("/a/b")
public String getEnpointB() {
return "Works!";
}
@GetMapping("/a/b/c")
public String getEnpointC() {
return "Works!";
}
}
/a uri의 GET은 무조건 인증되어야 허용 가능.
.mvcMatchers(HttpMethod.GET, "/a").authenticated()
C:\Users\user>curl -X GET http://localhost:8080/a
{"timestamp":"2023-08-04T02:12:23.459+00:00","status":401,"error":"Unauthorized","message":"","path":"/a"}
그다음 내가 헷갈려 하던 부분
MVC선택기로 경로 일치에 이용되는 일반적인 식
/a /a경로만
/a/* *연산자는 한 경로 이름만 대체. /a/b 또는 /a/c와는 일치, /a/b/c는 안됨
/a/** **연산자는 여러 경로 이름을 대체. 이 경우 /a /a/b a/b/c가 모두 일치
/a/{param} /a/경로에 매개변수 포함
/a/{param:regex} 매개변수값과 주어진 정규식이 일치할 경우 + /a경로
정규식 활용해서 이메일 형태일 경우만 인증 허용하려면
@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic();
http.authorizeRequests()
.mvcMatchers("/email/{email:.*(.+@.+\\.com)}")
.permitAll()
.anyRequest()
.denyAll();
}
}
@RestController
public class TestController {
@GetMapping("/email/{email}")
public String video(@PathVariable String email) {
return "Allowed for email " + email;
}
}
C:\Users\user>curl -X GET http://localhost:8080/email/test@naver.com
Allowed for email test@naver.com
C:\Users\user>curl -X GET http://localhost:8080/email/test@naver.c
{"timestamp":"2023-08-04T02:20:59.249+00:00","status":401,"error":"Unauthorized","message":"","path":"/email/test@naver.c"}
C:\Users\user>curl -X GET http://localhost:8080/email/test@naver.net
{"timestamp":"2023-08-04T02:21:04.696+00:00","status":401,"error":"Unauthorized","message":"","path":"/email/test@naver.net"}