스프링

스프링 시큐리티(spring security) 접근 권한

태태딩 2019. 6. 25. 23:59
반응형

사이트를 운영하다 보면 사용자의 권한을 정해줘야 할 때가 있습니다. 

예를 들어 사이트를 이용하는 일반적인 유저와 사이트의 전반적인 부분을 관리하는 매니저, 사이트 전체의 모든 것을  관리하는 관리자가 있을 수 있습니다.

이렇게 사용자의 권한을 나눠서 접근을 제한해야 하기 때문에, 그 권한을 다르게 주어 사용자를 구분해야 합니다.

접근 제한 설정

security-context.xml에 접근 제한을 설정합니다.

security-context.xml의 일부

	<security:http>
    
		<security:intercept-url pattern="/sample/all" access="permitAll"/>
		
		<security:intercept-url pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
		
		<security:intercept-url pattern="/sample/admin" access="hasRole('ROLE_ADMIN')"/>
		
		<security:form-login/>
        
	</security:http>
	
	<security:authentication-manager>
	
		<security:authentication-provider>
		
        	<security:user-service>
              <security:user name="member" password="{noop}member" 
              authorities="ROLE_MEMBER" />

              <security:user name="admin" password="{noop}admin" 
              authorities="ROLE_MEMBER,ROLE_ADMIN" />
              
            </security:user-serivce>
            
		</security:authentication-provider>
		
	</security:authentication-manager>

<security:intercept-url>에 접근을 설정하고 여러 권한을 가지는 사용자를 설정할 수도 있습니다.

접근 제한 메시지의 처리

특정 사용자가 로그인을 했지만 URI에 접근할 수 있는 권한이 없는 상황이 발생할 수도 있습니다. 이 경우에 접근 제한 에러 메시지를 보게 됩니다. 이 같은 경우 접근 제한에 대해서 AccessDeniedHandler를 직접 구현하거나 URI를 지정할 수 있습니다.

security-context.xml의 일부

	<security:http auto-config="true" use-expressions="true">
		<security:intercept-url pattern="/sample/all" access="permitAll"/>
		
		<security:intercept-url pattern="/sample/member" 
        		access="hasRole('ROLE_MEMBER')" />
		
		<security:intercept-url pattern="/sample/admin" 
        		access="hasRole('ROLE_ADMIN')"/>
		
		<security:form-login/>
        
		<security:access-denied-handler error-page="/accessError"/>
		
	</security:http>

위의 경우는 '/accessError'이라는 URI로 접근 제한시 보이는 화면을 처리하도록 한 것입니다.

com.security.controller에 CommonController 클래스를 생성해서 '/accessError'를 처리하도록 지정합니다.

CommonController클래스

package com.security.controller;

import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import lombok.extern.log4j.Log4j;

@Controller
@Log4j
public class CommonController {

		@GetMapping("/accessError")
		public void accessDenied(Authentication auth, Model model) {
			log.info("access Denied : "+ auth);
			model.addAttribute("msg", "접근권한이 없습니다.");
		}
}

간단한 에러메시지를 Model에 추가합니다, 그리고 Authentication 타입의 파라미터를 받도록 설계해서 필요한 경우 사용자의 정보를 확인할 수 있도록 합니다.

이제 views 폴더에 'accessError.jsp'파일을 생성합니다.

accessError.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
<%@ page import="java.util.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http//
www.w3.org/TR/html4/loose.dtd>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>접근권한 오류</h1>
	<h2>${msg}</h2>
</body>
</html>
반응형