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 © 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";
}
}
페이지마다 권한주기
- 공지사항 등록 - 로그인 한 관리자만 접근 가능
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_MEMBER')") - 공지사항 등록 - 로그인(인증) 한 관리자 또는 회원(인가)만 접근 가능
@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_MEMBER')")
@Secured({"ROLE_MEMBER","ROLE_ADMIN"}) - 공지사항 등록 - 로그인(인증) 한 관리자 이면서 회원(인가)만 접근 가능
@PreAuthorize("hasRole('ROLE_ADMIN') and hasRole('ROLE_MEMBER')") - 로그인한 사용자만 접근 가능(권한과 상관 없음)
@PreAuthorize("isAuthenticated()") - 로그인 안 한 사용자가 접근 가능 -> 로그인 한 사용자는 접근 불가
@PreAuthorize("isAnonymous()") - 누구나 접근 가능(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>
'Spring' 카테고리의 다른 글
[Spring] AOP (0) | 2024.08.13 |
---|---|
[Spring] 오류 페이지 (0) | 2024.08.13 |
[Spring] passwordEncoder, 로그인/로그아웃/자동로그인 (0) | 2024.08.12 |
[Spring] JDBC 이용한 인증 (0) | 2024.08.12 |
[Spring] 시큐리티 (0) | 2024.08.09 |