* 개발환경
- Vue CLI 4.4.6
- SpringBoot / SpringSecurity
- Tomcat 9.0
- JDK 1.8
- Gradle
찾기
클릭 시 doFind
메서드 실행. doFind
에 정의된 목적 url을 가지고 loginAjaxUtil.js로 분리해놓은 axios 로직을 탐.- FindPasswordModal.vue 일부
<template>
...
<button @click="doFind">찾기</button>
...
</template>
<script>
...
methods:{
doFind: async function() {
var result = await this.$ajax.post({
url: "/findPasswordPage.json", // controller 탈 mapper
data: this.$data // 넘길 데이터
});
}
}
...
</script>
- loginAjaxUtil.js 일부
import axios from 'axios' // axios 임포트
export default {
axiosCheck: function(param) { // 비동기 로직
if (typeof param == "string" ) {
return axios.post(param);
} else {
param.method = 'post';
if (param.data != null ) {
param.data = JSON.stringify(param.data);
}
param.headers = {'Content-Type' : "application/json"};
return axios(param);
}
},
post: async function(param) { // 비동기 처리 후 작업
var returnVal;
try {
var response = await this.axiosCheck(param); // axios 결과
console.log(response)
returnVal = response.data;
} catch(e) {
window.console.log(e);
}
return returnVal;
}
}
- FindPasswordController.java
...
@Controller
public class FindPasswordController {
...
@PostMapping("/findPasswordPage")
public Map<String,Object> findPassword(@RequestBody Map<String, Object> param) {
Map<String,Object> result = new HashMap<String,Object>();
System.out.println("param:::::::" + param);
return result;
}
}
(순서는 중요하지x)
스프링 시큐리티의 페이지별 접근 퍼미션 문제.
: SecurityConfiguration.java 중 HttpSecurity를 파라미터로 받는 configure 메서드에서 해당 uri 패턴에 대한 접근 설정이 없음.
ex) .antMatchers("주소or패턴").permitAll() 혹은 .hasAurhority("권한")
authorizeRequests()
에 .antMatchers("/findPasswordPage.json").permitAll()
을 추가함.
- SecurityConfiguration.java 중 configure(HttpSecurity)
...
@Configuration
@EnableWebSecurity
@ConditionalOnProperty(prefix = "spring.security", name = "enabled", matchIfMissing = false)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("/test*").permitAll()
.antMatchers("/loginPage.action").permitAll()
.antMatchers("/findPasswordPage.json").permitAll() // 접근 권한 설정 추가
.antMatchers("/login").permitAll()
.antMatchers("/registration").permitAll()
.antMatchers("/main").hasAuthority("ADMIN")
.antMatchers("/home").hasAuthority("ADMIN")
.anyRequest()
.authenticated()
...
}
}
권한 체크와 로그를 위해 각각 interceptor를 사용하고 있음.
현재 프로젝트는 어떤 uri에 접근할 땐 무조건 권한 체크 인터셉터를 먼저 타게 됨. 권한을 체크해야 하는 uri 목록은 모두 사용자의 권한(이미 로그인을 해서 사용자 인증이 완료됐다는 가정이 필요하게 됨)에 따라 접근 가능한 uri들이며, 모두 DB에 저장되어 있음. Interceptor는 사용자 인증 완료 시 이 uri 목록을 들고와서 Account 객체에 담아놓음.
현재 접근하고자 하는 uri는 현재 권한체크를 해야하는 uri패턴에 걸림. 그러나 이 uri는 로그인 이전에 필요한 화면(비밀번호 찾기 화면)이기 때문에 권한 체크가 필요하지 않고, DB에도 없기 때문에 uri목록에 없음. 그래서 AuthInterceptor는 false를 반환하고 이로 인해 해당 uri에 접근하지 못함.
excludePathPatterns()
에 "/findPasswordPage.json"
추가
- WebConfig.java(implements WebMvcConfigurer) 중 addInterceptors(InterceptorRegistry)
...
@Configuration
@EnableWebMvc
@ConfigurationProperties(prefix = "ui")
public class WebConfig implements WebMvcConfigurer {
...
@Override
public void addInterceptors(InterceptorRegistry registry) {
logger.info("addInterceptors start");
if(securityEnabled ) {
// AuthInterceptor() : 권한 체크 Interceptor
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/*.action")
.addPathPatterns("/*.json") // interceptor 패턴에 걸림
.excludePathPatterns("/test*.json", "/manifest.json","/findPasswordPage.json") // interceptor 제외 패턴에 추가
.excludePathPatterns(loginPageUrl);
...
}
}
...
}
여기까지 하면 해당 uri로 Controller가 타고 들어오기는 하지만 org.thymeleaf.exceptions.TemplateInputException: Error resolving template 에러가 발생.
2020-08-25 15:39:02.889 ERROR 22852 --- [nio-8080-exec-1] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-1] Exception processing template "findPasswordPage": Error resolving template [findPasswordPage], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [findPasswordPage], template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869)
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
at
...
Controller가 결과를 return해줄 화면을 지정하는 과정에서 해당 주소를 가진 화면을 찾지 못해서 발생하는 문제. 비동기 통신은 화면을 찾아서 리다이렉트 하지 않는 대신 결과 객체만 리턴하기 때문에 리턴할 화면이 지정되지 않음.
- FindPasswordController.java
...
@Controller
public class FindPasswordController {
@PostMapping("/findPasswordPage")
public @ResponseBody Map<String,Object> findPassword(@RequestBody Map<String, Object> param) {
Map<String,Object> result = new HashMap<String,Object>();
System.out.println("param:::::::" + param);
return result;
}
}
- FindPasswordController.java
@RestController
public class FindPasswordController {
...
}