Back-end/JAVA,Spring

스프링 시큐리티란? Spring Security

cheersHena 2020. 10. 7. 10:52
반응형

스프링 시큐리티 Spring Security 

 

▶ web.xml에 Spring-security 설정.

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
		/WEB-INF/config/spring/applicationContext.xml
	</param-value>
	</context-param>

filter-name: 반드시 springSecurityFilterChain 으로 준다. 

스프링시큐리티 내부에서 해당이름으로 클래스를 찾기때문.

해당필터가 적용될 URL패턴은 모든패턴을 의미하는 /* 로 준다.

 

* 주의

패턴을 예를들어 사용하는 웹페이지 확장자 .do등 이라고 해서 *.do를 주면안됨.

Spring security에서는 내부적으로 작업위해 사용되는 url들이 있는데 이 url들이 뒤에 확장자가 붙지 않는다.

 

ex) 로그인 인증관련 작업 url은 j_spring_sercurity_check 이다.(no확장자)

그래서 확장자로 패턴 줄 경우 로그인하지못하는 문제 발생.

반대로 모든패턴 /* 인 경우 css파일 등 스프링 시큐리티가 필요없는 경우가지도 스프링 시큐리티가 관여하게 되는가?

이경우에는 스프링시큐리티가 관여하지 않는 url패턴 지정가능.

url패턴지정시, 이미지파일이 들어있는 디렉토리나 css파일 디렉토리 등을 지정해준다.

 

 

web.xml - Root Context설정시 Spring security설정내용이 있는 xml 지정

 

applicationContext.xml

<import resource="extra/webmail-security.xml"/>

의 설정내용이 Root context로 올라가게된다

 

 

webmail-security.xml 예시 

<!-- CSRF Hidden Data input -->
	<beans:bean id="requestDataValueProcessor" class="org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor"/>

	<http pattern="/sens-static/**" security="none"/>
	<http pattern="/favicon.ico" security="none"/>
	<http pattern="/namoeditor/**" security="none"/>
	<http pattern="/error/**" security="none"/>
	<!-- 문서변환 등 URL Mapping 대상 -->
	<http pattern="/resources/**" security="none"/>

	<!-- 본문 미리보기 -->
	<http pattern="/mail/preview/body.do" security="none"/>
	<http pattern="/mail/preview/embed/image.do" security="none"/>

	<http auto-config="true" use-expressions="true" create-session="never" entry-point-ref="AuthenticationEntryPoint">

		<!-- API Controller -->
		<intercept-url pattern="/api/**" access="permitAll"/>
		
		<!-- API Controller -->
		<intercept-url pattern="/sso/login.do" access="permitAll"/>

		<intercept-url pattern="/index.jsp" access="permitAll"/>
        .
        .
        .

- security="none" : 스프링 시큐리티 적용하지 않음. (이미지디렉터리 예외처리)

- auto-config: 자동설정

- intercept-url : Spring security가 감시하는 url과 이 url이 접근가능한 권한을 정의하는 태그.

- pattern: url패턴 

- access: 해당 url 패턴을 이용할수있는 권한 지정.

 

ex) /account/ ~~.do 패턴의 url은 ROLE_SIMPLE 권한을 가지고 있어야 접근할수 있음.

<intercept-url pattern="/account/dormancyClear.do" access="hasRole('ROLE_SIMPLE')"/>
		<intercept-url pattern="/account/allowLogin.do" access="hasRole('ROLE_SIMPLE')"/>
		<intercept-url pattern="/account/dormancyLogin.do" access="hasRole('ROLE_SIMPLE')"/>
		<intercept-url pattern="/account/resetPassword.do" access="hasRole('ROLE_SIMPLE')"/>
        .
        .
        .

 

*<intercept-url> 태그를 지정 주의점 : 설정 순서

구체적인 URL 패턴을 먼저 설정하고 덜 구체적인 패턴을 나중에 설정해야 함

 

ex)

<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
<intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>

 

/admin/**과 /**을 비교시.

/admin/**는 admin 디렉토리 밑을 가리키는 모든 디렉토리와 파일을 의미하는 패턴이다.

그러나 /**는 모든 디렉토리와 파일을 가르키는 패턴이다.

즉 /admin/** 패턴이 /** 보다는 더 구체적인 패턴이다. 

Spring Security는 먼저 URL이 /admin/** 패턴을 만족하는지 검사하고 그걸 만족하지 않을 경우 /**을 본다.

만약 /** ROLE_USER 을 먼저 지정해버리면 모든 URL 이 /**을 만족하기 때문에 URL이 admin 디렉토리 하위를 가르킨다해도 /**를 먼저 만족시켜버리기 때문에 ROLE_USER 권한만 가지고 있어도 admin 디렉토리와 그 하위까지도 접근가능하게 되어버림.

 

Spring Security - CSRF Token

Spring Security 3.2 부터는 CSRF 공격에 대한 방어기능을 제공해주고있다.

CSRF공격은 한번 인증된 세션정보를 가지고 악의적인 목적을 가진 동일하게 구성된 페이지로 요청을 보내는 것인데

은행사이트의 경우를 가정한다면

사용자가 은행사이트에 로그인 한 뒤 로그아웃 하지않고 다른 웹사이트를 들어갔는데 그 사이트의 HTML코드가 은행의 페이지와 동일할 경우 사용자 의도와는 다르게 다른 사람에게 송금될 수 있다는것이다.

은행서버입장에서는 요청폼이 올바른 폼인지 아니면 다른곳에서 만들어진 폼인지 구분할 수 있는 고유값이 필요한데

그 대안중 하나가 Syncronized Token 패턴이다.

이 방법은 모든 요청에 세션 쿠키와 더불어 랜덤하게 생성되는 토큰을 HTTP 파라미터로 제공하는방법이다.

Spring Security는 CSRF공격을 막기 위해 랜덤토큰 인증방식을 제공해주고 있는것이다.

 

ex)

Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'

-> Spring Security 3.2 이상 버전에서 요청시 적절한 CSRF 토큰을 포함시켜주지 않으면 발생하는 에러내용.

 

Spring MVC가 제공하는 <form:form> 태그를 사용하면 CsrfRequestDataValueProcessor를 사용하여 CsrfToken이 자동으로 들어간다.

 

만약 일반 링크에서 위 메시지가 발생한다면 호출하는 URL의 파라미터에 토큰값을 추가해주면 된다.

* GET방식이나 URL에 토큰파라미터를 붙이게되면 토큰값이 노출되므로 hidden값으로 POST전송하는 방법이 안전함.

 

Action이나 onclick과 같은 javascript 사용시에는 hidden값으로 해당 토큰을 추가해주면된다.

ex)

function doSubmit (actionName, token, para_name, param_value){
//adminInsert.do?${_csrf.parameterName}=${_csrf.token}
//var actionUrl = actionName + "?"+ tname + "=" + token ;
var actionUrl = actionName;
	var form = document.forms[0];
    if (param_name != null){
    	var isType = $('input[name="'+param_name+'"]').val(); 
        if (isType != null && isType!= undefined ){
        	$('input[name="'+param_name+'"]').val(param_value);
        }else{
        	$('form').append('<input type="hidden" name ="'+param_name+'" value = "'+param_value+'">');
            //Spring Security 의 token값 설정
            $('form').append('<input type="hidden" name ="_csrf" value ="'+token+'">');
        }
    }
    
    forms.method = "POST";
    form.action =actionUrl;
    form.submit();

 

만약 특정 URL을 예외처리하고 싶다면 spring security .xml 파일에 아래와 같이 추가

 

<!-- 인증예외처리 -->

    <sec:http pattern="/css/**"         security="none" /> 

 

ex) 

<!-- CSRF 토큰 검사 예외처리 URL 을 등록 -->
		<beans:constructor-arg name="ignoreUrlPattern">
			<beans:list>
				<beans:value>/api/**</beans:value>
                <beans:value>/account/login.do</beans:value>
                <beans:value>/account/modal/login.do</beans:value>
                <beans:value>/mail/text/uploadFile.do</beans:value>
				<beans:value>/board/uploadAttachFile.do</beans:value>
				<beans:value>/mail/bigfile/download.do</beans:value>
				<beans:value>/log/lookup.do</beans:value>
				<beans:value>/account/nice/success.do</beans:value>
			</beans:list>
		</beans:constructor-arg>
	</beans:bean>

 

 

반응형