스프링 시큐리티 어노테이션

✅ 사용 어노테이션

@Secured 스프링 시큐리티 모듈을 지원하기 위한 어노테이션으로 초기부터 사용되었다.
@PreAuthorize 메서드가 실행되기 전에 적용할 접근 정책을 지정할 때 사용한다.
@PostAuthorize 메서드가 실행한 후에 적용할 접근 정책을 지정할 때 사용한다.

servlet-context 설정

Untitled

<security:global-method-security pre-post-annotations="enabled" secured-annotations="enabled"/>

security-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="<http://www.springframework.org/schema/beans>"
	xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"
	xmlns:security="<http://www.springframework.org/schema/security>"
	xsi:schemaLocation="<http://www.springframework.org/schema/beans> <http://www.springframework.org/schema/beans/spring-beans.xsd>
		<http://www.springframework.org/schema/security> <http://www.springframework.org/schema/security/spring-security.xsd>">
	
	<bean id="customAccessDenied" class="kr.or.ddit.security.CustomAccessDeniedhandler"></bean>
	<bean id="customLoginSuccess" class="kr.or.ddit.security.CustomLoginSuccessHandler"></bean>
	<!-- 사용자가 정의한 비밀번호 암호화 처리기를 빈으로 등록 -->
<!-- 	<bean id="customPasswordEncoder" class="kr.or.ddit.security.CustomNoOpPasswordEncoder"></bean> -->

	<!-- 스프링 시큐리티에서 제공하는 BCryptPasswordEncoder 클래스를 자바빈으로 등록 -->
	<bean id="bcryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>
	
	<!-- 사용자 정의 사용자 상세 기능 ***** 중요!! -->
	<bean id="customUserDetailsService" class="kr.or.ddit.security.CustomUserDetailsService"></bean>
	
	<security:http>
		
<!-- 이제 어노테이션으로 이용할꺼라 주석 처리 -->
**<!-- 		<security:intercept-url pattern="/board/list" access="permitAll"/> -->
<!-- 		<security:intercept-url pattern="/board/register" access="hasRole('ROLE_MEMBER')"/> -->
<!-- 		<security:intercept-url pattern="/notice/list" access="permitAll"/> -->
<!-- 		<security:intercept-url pattern="/notice/register" access="hasRole('ROLE_ADMIN')"/> -->**
		 s
		<!-- 로그인 성공 후 처리를 담당하는 처리자로 지정한다. -->
		<security:form-login login-page="/login" authentication-success-handler-ref="customLoginSuccess"/>
		
		<!-- 
			자동 로그인
			- 데이터 소스를 지정하고 테이을 이용해서 기존 로그인 정보를 기록
			- 쿠키의 유효시간을 짖어한다. (604800 : 7일)
		 -->
		<security:remember-me data-source-ref="dataSource" token-validity-seconds="604800"/>
		
		<!-- 로그아웃 처리를 위한  URI를 지정하고, 로그아웃 한 후에 세션을 무효화하기 위한 설정을 true로 한다.  -->
		<!-- 로그아웃을 하면 자동 로그인에 사용하는 쿠키도 삭제해 주도록 설정(delete-cookies) -->
		<security:logout logout-url="/logout" invalidate-session="true" delete-cookies="remember-me, JSESSION_ID"/>

		<!-- 등록한 CustomAccessDeniedHandler클래스를 활용한 거부 처리자로 지정한다. -->
		<security:access-denied-handler ref="customAccessDenied"/>
	</security:http>
	
	<!-- 지정된 아이디와 패스워드로 로그인이 가능하도록 설정한다. -->
	<security:authentication-manager>
		<security:authentication-provider user-service-ref="customUserDetailsService">
			
			<security:password-encoder ref="bcryptPasswordEncoder"/>
		</security:authentication-provider>
	</security:authentication-manager>
</beans>
package kr.or.ddit.controller;

import java.security.Principal;
import java.util.Iterator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/board")
public class BoardController {

	private static final Logger log = LoggerFactory.getLogger(BoardController.class);
	
	// 일반게시판 목록 화면
	@RequestMapping(value="/list")
	public String list() {
		log.info("list() 실행...!");
		return "board/list";
	}
	
	// 일반게시판 등록 화면
	@PreAuthorize("hasRole('ROLE_MEMBER')")
	@RequestMapping(value="/register", method = RequestMethod.GET)
	public String registerForm(Principal principal) {
		log.info("registerForm() 실행...!");
		
		// 방법 1)
		log.info("사용자명 : " + principal.getName());
		
		// 방법2)
		User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		log.info("user.username : " + user.getUsername());
		log.info("user.password : " + user.getPassword());

		Iterator<GrantedAuthority> ite = user.getAuthorities().iterator();
		while(ite.hasNext()) {
			log.info("auth : " + ite.next().getAuthority());
		}
		
		return "board/register";
	}
}
package kr.or.ddit.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/notice")
public class NoticeController {
	
	private static final Logger log = LoggerFactory.getLogger(NoticeController.class);
	
	// 공지사한 게시판 목록 화면
	@RequestMapping(value="/list", method = RequestMethod.GET)
	public String list() {
		log.info("list() 실행...!");
		return "notice/list";
	}
	
	// 공지사항 게시판 등록 화면
	@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_MEMBER')")
	@RequestMapping(value="/register", method = RequestMethod.GET)
	public String registerForm() {
		log.info("registerForm() 실행...!");
		return "notice/register";
	}
}

MEMBER 권한으로 로그인을 하면 MemberController에서 어노테이션 이용했던 부분에 log를 작성한 것을 확인해보면 정보가 잘 나타난 것을 확인할 수 있다.

Untitled