[백업][가리사니] csrf : 2. 스프링 시큐리티를 이용한 적용 (확장 태그 미지원 템플릿을 위한)
http, security, spring

이 문서는 가리사니 개발자 포럼에 올렸던 글의 백업 파일입니다. 오래된 문서가 많아 현재 상황과 맞지 않을 수 있습니다.

CSRF 시리즈

스프링 시큐리티 설치

스프링 시큐리티 시리즈 스프링 시큐리티 설치시 기본으로 csrf 가 작동합니다.

Mustache 예제

또 여러가지 지원을 해주지 않는 머스터치를 위해 인터셉터를 추가해보겠습니다.

<html>
<body>
	<form method="POST" enctype="multipart/form-data" action="/넘길페이지">
		<div>
			<input type="submit" value="Upload" />
		</div>
	</form>
</body>
</html>

보통 위와 같이 넘기게 될경우 403 (서비스 거부) 오류가 날 것입니다. 머스터치에선 바로 시큐리티를 빼올 수 없기 때문에 HandlerInterceptor 를 써보겠습니다.

<html>
<body>
	<form method="POST" enctype="multipart/form-data" action="/넘길페이지">
		<div>
			<input type="hidden" name="_csrf" value="token" />
			<input type="submit" value="Upload" />
		</div>
	</form>
</body>
</html>

_csrf.token 으로 값을 주었습니다. 참고 HandlerInterceptorAdapter

@Component
public class CsrfInterceptor extends HandlerInterceptorAdapter
{
	@Override
	public void postHandle
	(
		HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView modelAndView
	) throws Exception
	{
		if (modelAndView != null)
		{
			// _csrf 를 찾아.
			modelAndView.addObject("_csrf", new Mustache.Lambda()
			{
				public void execute(Template.Fragment frag, Writer out) throws IOException
				{
					// token 에 해당할 경우
					if ("token".equals(frag.execute()))
					{
						// 토큰으로 치환
						out.write( ((CsrfToken) req.getAttribute(CsrfToken.class.getName())).getToken() );
					}
				}
			});
		}

		super.postHandle(req, res, handler, modelAndView);
	}
}

인터셉터 추가

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter
{
	@Autowired
	CsrfInterceptor csrfInterceptor;

	@Override
	public void addInterceptors(InterceptorRegistry registry)
	{
		registry.addInterceptor(csrfInterceptor);
	}
}

실행

소스보기를 누르면 아래와같이 추가되어있을겁니다. 물론 저 벨류는 랜덤한 값으로 보냅니다. (강의 1장 참고)

<html>
<body>
	<form method="POST" enctype="multipart/form-data" action="/넘길페이지">
		<div>
			<input type="hidden" name="_csrf" value="a60159ae-9b7f-45dc-9c97-3a5f14a39cbd" />
			<input type="submit" value="Upload" />
		</div>
	</form>
</body>
</html>

그리고 넘겼을 경우 403없이 정상 작동할 경우 성공!!