Spring

[Spring] 페이지 별 권한 주기 @PreAuthorize

아잠만_ 2024. 8. 13. 12:44

tiles

freelancer tiles 추가

WEB_INF/spring/tiles-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC 
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" 
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<!-- tiles 설정 -->
<tiles-definitions>
   <!-- main layout -->
   <definition name="tiles-layout" template="/WEB-INF/views/tiles/index.jsp">
      <put-attribute name="header" value="/WEB-INF/views/tiles/header.jsp" />
      <put-attribute name="aside" value="/WEB-INF/views/tiles/aside.jsp" />
      <put-attribute name="body" value="" />
      <put-attribute name="footer" value="/WEB-INF/views/tiles/footer.jsp" />
   </definition>
   <!-- name의 */*은 body의 value에서 1과 2에 해당
      controller에서 forwarding 시 return "1/2";
      return "book/list";
    -->
   <definition name="*/*" extends="tiles-layout">
      <put-attribute name="body" value="/WEB-INF/views/{1}/{2}.jsp" />
   </definition>
   
   
   <!-- freelancer layout 시작 -->
   <definition name="freelancer-layout" template="/WEB-INF/views/freelancerTiles/index.jsp">
      <put-attribute name="header" value="/WEB-INF/views/freelancerTiles/header.jsp" />
      <put-attribute name="body" value="" />
      <put-attribute name="footer" value="/WEB-INF/views/freelancerTiles/footer.jsp" />
   </definition>
   <!-- name의 freelancer/member/*은 body의 value에서 1에 해당
      controller에서 forwarding 시 return "1/2";
      return "freelancer/member/list";
    -->
   <definition name="freelancer/member/*" extends="freelancer-layout">
      <put-attribute name="body" value="/WEB-INF/views/freelancer/member/{1}.jsp" />
   </definition>
   <!-- freelancer layout 끝 -->

   
   <!--  return "accessError" -->
   <definition name="tiles-layout2" template="/WEB-INF/views/tiles/index.jsp">
      <put-attribute name="header" value="/WEB-INF/views/tiles/header.jsp" />
      <put-attribute name="aside" value="/WEB-INF/views/tiles/aside.jsp" />
      <put-attribute name="body" value="" />
      <put-attribute name="footer" value="/WEB-INF/views/tiles/footer.jsp" />
   </definition>
   <definition name="*" extends="tiles-layout2">
      <put-attribute name="body" value="/WEB-INF/views/{1}.jsp" />
   </definition>
</tiles-definitions>

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> 
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
        <meta name="description" content="" />
        <meta name="author" content="" />
        <title>Freelancer - Start Bootstrap Theme</title>
        <!-- Favicon-->
        <link rel="icon" type="image/x-icon" href="/resources/freelancer/assets/favicon.ico" />
        <!-- Font Awesome icons (free version)-->
		<script type="text/javascript" src="/resources/js/jquery.min.js"></script>  
        <script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
        <!-- Google fonts-->
        <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css" />
        <link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css" />
        <!-- Core theme CSS (includes Bootstrap)-->
        <link href="/resources/freelancer/css/styles.css" rel="stylesheet" />
    </head>
    <body id="page-top">
		<!--// header.jsp 시작 //-->
			<tiles:insertAttribute name="header" />
		<!--// header.jsp 끝 //-->

        <!-- Portfolio Section-->
        <section class="page-section portfolio" id="portfolio">
            <div class="container" style="padding: 50px 0 0">
               <tiles:insertAttribute name="body" />
            </div>
        </section>
        
        <!--// footer.jsp 시작 //-->
			<tiles:insertAttribute name="footer" />
		<!--// footer.jsp 끝 //-->
		
        <!-- Portfolio Modals-->
        <!-- Portfolio Modal 1-->
        <div class="portfolio-modal modal fade" id="portfolioModal1" tabindex="-1" aria-labelledby="portfolioModal1" aria-hidden="true">
            <div class="modal-dialog modal-xl">
                <div class="modal-content">
                    <div class="modal-header border-0"><button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button></div>
                    <div class="modal-body text-center pb-5">
                        <div class="container">
                            <div class="row justify-content-center">
                                <div class="col-lg-8">
                                    <!-- Portfolio Modal - Title-->
                                    <h2 class="portfolio-modal-title text-secondary text-uppercase mb-0">Log Cabin</h2>
                                    <!-- Icon Divider-->
                                    <div class="divider-custom">
                                        <div class="divider-custom-line"></div>
                                        <div class="divider-custom-icon"><i class="fas fa-star"></i></div>
                                        <div class="divider-custom-line"></div>
                                    </div>
                                    <!-- Portfolio Modal - Image-->
                                    <img class="img-fluid rounded mb-5" src="/resources/freelancer/assets/img/portfolio/cabin.png" alt="..." />
                                    <!-- Portfolio Modal - Text-->
                                    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
                                    <button class="btn btn-primary" data-bs-dismiss="modal">
                                        <i class="fas fa-xmark fa-fw"></i>
                                        Close Window
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- Portfolio Modal 2-->
        <div class="portfolio-modal modal fade" id="portfolioModal2" tabindex="-1" aria-labelledby="portfolioModal2" aria-hidden="true">
            <div class="modal-dialog modal-xl">
                <div class="modal-content">
                    <div class="modal-header border-0"><button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button></div>
                    <div class="modal-body text-center pb-5">
                        <div class="container">
                            <div class="row justify-content-center">
                                <div class="col-lg-8">
                                    <!-- Portfolio Modal - Title-->
                                    <h2 class="portfolio-modal-title text-secondary text-uppercase mb-0">Tasty Cake</h2>
                                    <!-- Icon Divider-->
                                    <div class="divider-custom">
                                        <div class="divider-custom-line"></div>
                                        <div class="divider-custom-icon"><i class="fas fa-star"></i></div>
                                        <div class="divider-custom-line"></div>
                                    </div>
                                    <!-- Portfolio Modal - Image-->
                                    <img class="img-fluid rounded mb-5" src="/resources/freelancer/assets/img/portfolio/cake.png" alt="..." />
                                    <!-- Portfolio Modal - Text-->
                                    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
                                    <button class="btn btn-primary" data-bs-dismiss="modal">
                                        <i class="fas fa-xmark fa-fw"></i>
                                        Close Window
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- Portfolio Modal 3-->
        <div class="portfolio-modal modal fade" id="portfolioModal3" tabindex="-1" aria-labelledby="portfolioModal3" aria-hidden="true">
            <div class="modal-dialog modal-xl">
                <div class="modal-content">
                    <div class="modal-header border-0"><button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button></div>
                    <div class="modal-body text-center pb-5">
                        <div class="container">
                            <div class="row justify-content-center">
                                <div class="col-lg-8">
                                    <!-- Portfolio Modal - Title-->
                                    <h2 class="portfolio-modal-title text-secondary text-uppercase mb-0">Circus Tent</h2>
                                    <!-- Icon Divider-->
                                    <div class="divider-custom">
                                        <div class="divider-custom-line"></div>
                                        <div class="divider-custom-icon"><i class="fas fa-star"></i></div>
                                        <div class="divider-custom-line"></div>
                                    </div>
                                    <!-- Portfolio Modal - Image-->
                                    <img class="img-fluid rounded mb-5" src="/resources/freelancer/assets/img/portfolio/circus.png" alt="..." />
                                    <!-- Portfolio Modal - Text-->
                                    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
                                    <button class="btn btn-primary" data-bs-dismiss="modal">
                                        <i class="fas fa-xmark fa-fw"></i>
                                        Close Window
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- Portfolio Modal 4-->
        <div class="portfolio-modal modal fade" id="portfolioModal4" tabindex="-1" aria-labelledby="portfolioModal4" aria-hidden="true">
            <div class="modal-dialog modal-xl">
                <div class="modal-content">
                    <div class="modal-header border-0"><button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button></div>
                    <div class="modal-body text-center pb-5">
                        <div class="container">
                            <div class="row justify-content-center">
                                <div class="col-lg-8">
                                    <!-- Portfolio Modal - Title-->
                                    <h2 class="portfolio-modal-title text-secondary text-uppercase mb-0">Controller</h2>
                                    <!-- Icon Divider-->
                                    <div class="divider-custom">
                                        <div class="divider-custom-line"></div>
                                        <div class="divider-custom-icon"><i class="fas fa-star"></i></div>
                                        <div class="divider-custom-line"></div>
                                    </div>
                                    <!-- Portfolio Modal - Image-->
                                    <img class="img-fluid rounded mb-5" src="/resources/freelancer/assets/img/portfolio/game.png" alt="..." />
                                    <!-- Portfolio Modal - Text-->
                                    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
                                    <button class="btn btn-primary" data-bs-dismiss="modal">
                                        <i class="fas fa-xmark fa-fw"></i>
                                        Close Window
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- Portfolio Modal 5-->
        <div class="portfolio-modal modal fade" id="portfolioModal5" tabindex="-1" aria-labelledby="portfolioModal5" aria-hidden="true">
            <div class="modal-dialog modal-xl">
                <div class="modal-content">
                    <div class="modal-header border-0"><button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button></div>
                    <div class="modal-body text-center pb-5">
                        <div class="container">
                            <div class="row justify-content-center">
                                <div class="col-lg-8">
                                    <!-- Portfolio Modal - Title-->
                                    <h2 class="portfolio-modal-title text-secondary text-uppercase mb-0">Locked Safe</h2>
                                    <!-- Icon Divider-->
                                    <div class="divider-custom">
                                        <div class="divider-custom-line"></div>
                                        <div class="divider-custom-icon"><i class="fas fa-star"></i></div>
                                        <div class="divider-custom-line"></div>
                                    </div>
                                    <!-- Portfolio Modal - Image-->
                                    <img class="img-fluid rounded mb-5" src="/resources/freelancer/assets/img/portfolio/safe.png" alt="..." />
                                    <!-- Portfolio Modal - Text-->
                                    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
                                    <button class="btn btn-primary" data-bs-dismiss="modal">
                                        <i class="fas fa-xmark fa-fw"></i>
                                        Close Window
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- Portfolio Modal 6-->
        <div class="portfolio-modal modal fade" id="portfolioModal6" tabindex="-1" aria-labelledby="portfolioModal6" aria-hidden="true">
            <div class="modal-dialog modal-xl">
                <div class="modal-content">
                    <div class="modal-header border-0"><button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button></div>
                    <div class="modal-body text-center pb-5">
                        <div class="container">
                            <div class="row justify-content-center">
                                <div class="col-lg-8">
                                    <!-- Portfolio Modal - Title-->
                                    <h2 class="portfolio-modal-title text-secondary text-uppercase mb-0">Submarine</h2>
                                    <!-- Icon Divider-->
                                    <div class="divider-custom">
                                        <div class="divider-custom-line"></div>
                                        <div class="divider-custom-icon"><i class="fas fa-star"></i></div>
                                        <div class="divider-custom-line"></div>
                                    </div>
                                    <!-- Portfolio Modal - Image-->
                                    <img class="img-fluid rounded mb-5" src="/resources/freelancer/assets/img/portfolio/submarine.png" alt="..." />
                                    <!-- Portfolio Modal - Text-->
                                    <p class="mb-4">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Mollitia neque assumenda ipsam nihil, molestias magnam, recusandae quos quis inventore quisquam velit asperiores, vitae? Reprehenderit soluta, eos quod consequuntur itaque. Nam.</p>
                                    <button class="btn btn-primary" data-bs-dismiss="modal">
                                        <i class="fas fa-xmark fa-fw"></i>
                                        Close Window
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- Bootstrap core JS-->
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
        <!-- Core theme JS-->
        <script src="/resources/freelancer/js/scripts.js"></script>
        <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
        <!-- * *                               SB Forms JS                               * *-->
        <!-- * * Activate your form at https://startbootstrap.com/solution/contact-forms * *-->
        <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
        <script src="https://cdn.startbootstrap.com/sb-forms-latest.js"></script>
    </body>
</html>

header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
<script>
$(function(){
	$('#alogout').on('click',function(){
		$('#logoutf').submit();
	})
})
</script>
<!-- Navigation-->
<nav class="navbar navbar-expand-lg bg-secondary text-uppercase fixed-top" id="mainNav">
    <div class="container">
        <a class="navbar-brand" href="#page-top">Start Bootstrap</a>
        <button class="navbar-toggler text-uppercase font-weight-bold bg-primary text-white rounded" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
            Menu
            <i class="fas fa-bars"></i>
        </button>
        <div class="collapse navbar-collapse" id="navbarResponsive">
            <ul class="navbar-nav ms-auto">
                <li class="nav-item mx-0 mx-lg-1"></li>
                <li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#portfolio">Portfolio</a></li>
                <li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#about">About</a></li>
                <li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#contact">Contact</a></li>
            <sec:authorize access="isAuthenticated()">
                <li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#" id="alogout">로그아웃</a></li>
				<form action="/logout" method="post" id="logoutf">
					 <sec:csrfInput/>
				</form>
			</sec:authorize>
            </ul>
        </div>
    </div>
</nav>

footer.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>

<!-- Footer-->
<footer class="footer text-center">
    <div class="container">
        <div class="row">
            <!-- Footer Location-->
            <div class="col-lg-4 mb-5 mb-lg-0">
                <h4 class="text-uppercase mb-4">Location</h4>
                <p class="lead mb-0">
                    2215 John Daniel Drive
                    <br />
                    Clark, MO 65243
                </p>
            </div>
            <!-- Footer Social Icons-->
            <div class="col-lg-4 mb-5 mb-lg-0">
                <h4 class="text-uppercase mb-4">Around the Web</h4>
                <a class="btn btn-outline-light btn-social mx-1" href="#!"><i class="fab fa-fw fa-facebook-f"></i></a>
                <a class="btn btn-outline-light btn-social mx-1" href="#!"><i class="fab fa-fw fa-twitter"></i></a>
                <a class="btn btn-outline-light btn-social mx-1" href="#!"><i class="fab fa-fw fa-linkedin-in"></i></a>
                <a class="btn btn-outline-light btn-social mx-1" href="#!"><i class="fab fa-fw fa-dribbble"></i></a>
            </div>
            <!-- Footer About Text-->
            <div class="col-lg-4">
                <h4 class="text-uppercase mb-4">About Freelancer</h4>
                <p class="lead mb-0">
                    Freelance is a free to use, MIT licensed Bootstrap theme created by
                    <a href="http://startbootstrap.com">Start Bootstrap</a>
                    .
                </p>
            </div>
        </div>
    </div>
</footer>

<!-- Copyright Section-->
<div class="copyright py-4 text-center text-white">
    <div class="container"><small>Copyright &copy; Your Website 2023</small></div>
</div>

FreelancerController.java

실행을 위한 controller

package kr.or.ddit.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/freelancer/member")
@Controller
public class FreelancerController {
	
	@GetMapping("/list")
	public String list() {
		return "freelancer/member/list";
	}
}

페이지마다 권한주기

  1. 공지사항 등록 - 로그인 한 관리자만 접근 가능
       @PreAuthorize("hasRole('ROLE_ADMIN')")
       @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_MEMBER')")
  2. 공지사항 등록 - 로그인(인증) 한 관리자 또는 회원(인가)만 접근 가능
       @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_MEMBER')")   
       @Secured({"ROLE_MEMBER","ROLE_ADMIN"})
  3. 공지사항 등록 - 로그인(인증) 한 관리자 이면서 회원(인가)만 접근 가능
       @PreAuthorize("hasRole('ROLE_ADMIN') and hasRole('ROLE_MEMBER')")
  4. 로그인한 사용자만 접근 가능(권한과 상관 없음)
       @PreAuthorize("isAuthenticated()")
  5. 로그인 안 한 사용자가 접근 가능 -> 로그인 한 사용자는 접근 불가
       @PreAuthorize("isAnonymous()")
  6. 누구나 접근 가능(PreAuthorize 생략)

servlet-context.xml

스프링 시큐리티 애너테이션을 활성화
    - pre-post-annotations="enabled" -> 골뱅이PreAuthorize, 골뱅이PostAuthorize 활성화
      *** PreAuthorize : 특정 메소드를 실행하기 전에 role 체킹
      PostAuthorize : 특정 메소드를 실행한 후에 role 체킹
    - secured-annotations="enabled" -> 골뱅이Secured를 활성화
      Secured : 스프링 시큐리티 모듈을 지원하기 위한 애너테이션

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
	xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:security="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/security 
      	http://www.springframework.org/schema/security/spring-security-4.2.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing 
		infrastructure -->

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<!-- static folder설정(정적 폴더 설정)=>css, images, upload, js 서버에서 앞서 처리될 필요가 
		없는 정적 리소스 파일을 처리하는 역할 수행 웹 애플리케이션의 물리적 경로 이름을 설정하고 이 경로에 정적 리소스 파일들을 저장하면 
		소스 코드나 웹 브라우저의 주소창에서 해당 리소스의 경로를 사용하여 직접 접속할 수 있음 정적 리소스란 클라이언트에서 요청이 들어왔을 
		때 요청 리소스가 이미 만들어져 있어 그대로 응답하는 것 mapping : 웹 요청 경로 패턴을 설정. 컨텍스트 경로를 제외한 나머지 
		부분의 경로와 매핑 location : 웹 애플리케이션 내에서 실제 요청 경로의 패턴에 해당하는 자원 위치를 설정. 위치가 여러 곳이면 
		각 위치를 쉼표로 구분 -->
	<!-- http://localhost/resources/ -->
	<resources mapping="/resources/**" location="/resources/" />

	<resources  mapping="/upload/**" location="file:\\\c:\\upload\\"></resources>

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
		in the /WEB-INF/views directory -->
	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

	<context:component-scan
		base-package="kr.or.ddit" />

	<!-- Tile -->
	<beans:bean id="tilesConfigurer"
		class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
		<beans:property name="definitions">
			<beans:list>
				<beans:value>/WEB-INF/spring/tiles-config.xml</beans:value>
			</beans:list>
		</beans:property>
	</beans:bean>
	<!-- UrlBasedViewResolver tilesViewResolver = new UrlBasedViewResolver(); -->
	<beans:bean id="tilesViewResolver"
		class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<beans:property name="viewClass"
			value="org.springframework.web.servlet.view.tiles3.TilesView" />
		<beans:property name="order" value="1" />
	</beans:bean>
	
	<!-- 스프링 시큐리티 애너테이션을 활성화
    - pre-post-annotations="enabled" -> 골뱅이PreAuthorize, 골뱅이PostAuthorize 활성화
      *** PreAuthorize : 특정 메소드를 실행하기 전에 role 체킹
      PostAuthorize : 특정 메소드를 실행한 후에 role 체킹
    - secured-annotations="enabled" -> 골뱅이Secured를 활성화
      Secured : 스프링 시큐리티 모듈을 지원하기 위한 애너테이션
    -->
	<security:global-method-security pre-post-annotations="enabled"
	secured-annotations="enabled"/>
	
</beans:beans>

FreelancerController.java

package kr.or.ddit.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

// 클래스 자체에서 걸 수도 있음
@PreAuthorize("hasRole('ROLE_MEMBER')")
@RequestMapping("/freelancer/member")
@Controller
public class FreelancerController {
	
	//ROLE_MEMBER 권한을 가진 사용자만 접근 가능
	// PreAuthorize : 메소드 실행 전에 권한 체킹
	//@PreAuthorize("hasRole('ROLE_MEMBER')")
	@GetMapping("/list")
	public String list() {
		return "freelancer/member/list";
	}
}

로그인 성공시 페이지 이동

CustomLoginSuccessHandler.java

package kr.or.ddit.security;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
	@Override
		public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
				Authentication auth) throws ServletException, IOException {
			log.info("로그인 성공");
			// auth.getPrincipal() : 사용자 정보를 가져옴
			// 시큐리티에서 사용자 정보는 User 클래스의 객체로 저장됨(CustomUser.java를 참고)
			// 시큐리티 user로 import할 것
			User customUser = (User) auth.getPrincipal();
			
			// 사용자 아이디를 리턴
			String username = customUser.getUsername();
			log.info("username : "+username);
			
			//auth.getAuthorities() -> 권한들(ROLE_MEMBER,ROLE_ADMIN)
		    //authority.getAuthority() : ROLE_MEMBER
			List<String> roleNames = new ArrayList<String>();
			auth.getAuthorities().forEach(authority->{
				roleNames.add(authority.getAuthority());
			});
			log.info("roleNames : "+roleNames);
			
	      if(roleNames.contains("ROLE_ADMIN")) {
	         response.sendRedirect("/notice/regist");
	         return;
	      }
	      
	      if(roleNames.contains("ROLE_MEMBER")) {
	         response.sendRedirect("/freelancer/member/list");
	         return;
	      }
			
			super.onAuthenticationSuccess(request, response, auth);
		}
}

authorize access

역할을 지정해 해당하는 역할의 사람만 보이게 하는 메뉴 설정

header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
<script>
$(function(){
	$('#alogout').on('click',function(){
		$('#logoutf').submit();
	})
})
</script>
<!-- Navigation-->
<nav class="navbar navbar-expand-lg bg-secondary text-uppercase fixed-top" id="mainNav">
    <div class="container">
        <a class="navbar-brand" href="#page-top">Start Bootstrap</a>
        <button class="navbar-toggler text-uppercase font-weight-bold bg-primary text-white rounded" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
            Menu
            <i class="fas fa-bars"></i>
        </button>
        <div class="collapse navbar-collapse" id="navbarResponsive">
            <ul class="navbar-nav ms-auto">
                <li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#portfolio">Portfolio</a></li>
                
                <!-- 관리자에게만 보이는 메뉴 -->
                <sec:authorize access="hasRole('ROLE_ADMIN')">
                	<li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#about">About</a></li>
                </sec:authorize>
                
                <li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#contact">Contact</a></li>
            <sec:authorize access="isAuthenticated()">
                <li class="nav-item mx-0 mx-lg-1"><a class="nav-link py-3 px-0 px-lg-3 rounded" href="#" id="alogout">로그아웃</a></li>
				<form action="/logout" method="post" id="logoutf">
					 <sec:csrfInput/>
				</form>
			</sec:authorize>
            </ul>
        </div>
    </div>
</nav>