이번 강의에서는 Basic Auth 외에도 일반적인 CSRF 가 필요한 웹사이트와 함께 운용하기 위해서 별도의 Configuration 을 추가합니다. 프로젝트가 갑자기 이전 강의 거로 돌아가는게 제일 당황스럽던;
@Configuration 을 별도로 추가하자
강의에서는 사전에 준비해두신 프로젝트로 진행해서 BasicAuth configuration 을 한 번 더 추가했는데요, 저는 이전 강의에서 직접 만들었던 프로젝트에서 이어서 작업하므로 거꾸로 일반 웹페이지 형식으로 받는 Configuration 을 추가해야 합니다.
기존 Basic Auth 설정을 /api/v1 로 이동
일단 기존 핸들러들을 /api 아래로 다 옮겨보겠습니다.
@RestController
@RequestMapping("/api/v1")
class GreetingApiController {
@GetMapping("/greeting")
fun greeting() = "Hello from API!"
@PostMapping("/greeting")
fun greeting(@RequestBody name: String) = "Hello from API, ${name}!"
}
설정도 옮기고요.
- Enable* 두 개는 웹 서비스를 해줄 곳에서 추가할 거고 두 개 있으면 오류가 나므로 주석처리합니다.
- configure 도 마찬가지로 주석처리하긴 했는데... 음, 잘 되네요.
- @Order(1) 을 추가해서 이 설정이 먼저 처리되도록 했습니다.
@Order(1)
@Configuration
//@EnableWebSecurity // << comment out
//@EnableGlobalMethodSecurity // << comment out
open class ApiSecurityConf: WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.antMatcher("/api/**") // << new
.csrf().disable()
.authorizeRequests().anyRequest().authenticated()
.and()
.httpBasic()
}
// override fun configure(auth: AuthenticationManagerBuilder) {
// auth.inMemoryAuthentication()
// .withUser(
// // WARNING: This method is considered unsafe for production and is only intended for sample applications.
// User.withDefaultPasswordEncoder()
// // 이 밑은 deprecated 나 경고가 없습니다.
// .username("user1")
// .password("1111")
// .roles("USER")
// .build()
// )
// }
}
웹서비스 설정 및 핸들러 추가
다른 건 몰라도 thymeleaf 하나만큼은 쓸 줄 몰라서 실습 소스 저장소를 봐야만 했습니다.
먼저 Order 는 2구요, 원본 강의에서는 이전에 했던 걸 가져와서 하면서 커스텀 필터도 적용되는 걸 보여줬는데, 강의에서 확인했으니 굳이 그걸 제가 하진 않겠습니다.
@Order(2)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
open class SecurityConf: WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.formLogin().and()
.authorizeRequests().antMatchers("/").permitAll()
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.logout { it.logoutSuccessUrl("/") }
}
override fun configure(auth: AuthenticationManagerBuilder) {
// super.configure(auth)
auth.inMemoryAuthentication()
.withUser(
// WARNING: This method is considered unsafe for production and is only intended for sample applications.
User.withDefaultPasswordEncoder()
// 이 밑은 deprecated 나 경고가 없습니다.
.username("user1")
.password("1111")
.roles("USER")
.build()
)
}
override fun configure(web: WebSecurity) {
web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations())
}
}
컨트롤러는 이렇게. ThymeLeaf 를 경유해서 화면에 템플릿으로 값을 뿌려주려면 model 에 값을 넣어야 합니다. 일단 잘은 모르겠는데 이름을 넣으면 나오기는 합니다.
@Controller // RestController 이면 뷰 렌더링이 안 됨
class GreetingController {
@GetMapping("/greeting")
fun greeting(): String {
return "greeting"
}
@PostMapping("/greeting")
fun greeting(@RequestParam(name = "username") username: String, model: Model): String {
model.addAttribute("username", username)
return "greeting_with_result"
}
}
html 은 resources/templates 경로에 적당히 넣습니다.
index.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.css}">
<link rel="stylesheet" th:href="@{/css/index.css}">
</head>
<body>
index
<ul>
<li><a href="/greeting">greeting</a></li>
<li><form th:action="@{/greeting}" th:object="${String}" method="post">
<input name="name"/>
<input type="submit">greeting (post)</input>
</form></li>
<li><form th:action="@{/logout}" method="post"><input type="submit">logout</button>
</form></li>
</ul>
</body>
</html>
greeting.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello!
</body>
</html>
greeting_with_result.html
여기서 골머리를 썩인게, th:text="${패러미터}" 식이어야지 템플릿 채우기가 됩니다. 대체 뭔; 저는 일반 템플릿 엔진처럼 그냥 본문에 떡하니 ${패러미터} 하고 쓰면 당연히 될 줄 알았죠. 그런 거 아니었습니다.
https://spring.io/guides/gs/handling-form-submission/
https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html
https://www.baeldung.com/spring-thymeleaf-request-parameters
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
hello! <span th:text="${username}">몰?루</span>!
</body>
</html>
이렇게 해놓으면 post 및 login 이 막히는 것도 확인해볼 수 있습니다. CSRF야 뭐 개발자 도구 열어보면 되겠죠?
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스: https://bit.ly/37BpXiC
#패스트캠퍼스 #패캠챌린지 #직장인인강 #직장인자기계발 #패스트캠퍼스후기 #한번에끝내는JavaSpring웹개발마스터초격차패키지Online
내일이 마지막입니다. 시큐리티 공부는 어디로 가는가...
'FastCampus - 한번에 끝내는 Java|Spring 웹 개발 > 04-2 시큐리티' 카테고리의 다른 글
Security 02-06: DB에 계정 넣기 - 패스트캠퍼스 챌린지 50일차 (0) | 2022.03.14 |
---|---|
Security 02-05: Basic Auth - 패스트캠퍼스 챌린지 48일차 (0) | 2022.03.12 |
Security 02-04: Authentication 메커니즘 - 패스트캠퍼스 챌린지 47일차 (0) | 2022.03.11 |
Security 02: 전체 구조 - 패스트캠퍼스 챌린지 46일차 (0) | 2022.03.10 |
Security 01: 개요 및 맛보기 - 패스트캠퍼스 챌린지 42일차 (0) | 2022.03.06 |