SECURITY

팡태(❁´◡`❁)·2022년 4월 5일
0

SPRING_20220328

목록 보기
8/24
  • HomeController.java
  package com.example.controller;

import javax.servlet.http.HttpSession;

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

@Controller
public class HomeController {
    
    // 서버주소: 포트번호/컨텍스트PATH/home
    // 127.0.0.1:9090/ROOT/home
    @GetMapping(value = { "/", "/home" })
    
    //여기
    public String homeGet(HttpSession httpSession){
        System.out.println(httpSession.getAttribute("BACKURL"));
        
        return "home";
    }
}

  • MemberController.java
    @PostMapping(value="/login")
    public String loginPOST(
        @RequestParam(name="uemail") String em,
        @RequestParam(name="upw") String pw) {
            System.out.println(em);
            System.out.println(pw);

			// 여기
            MemberDTO member = mMapper.memberEmail(em);
            
            if(member != null) {
                System.out.println(member.toString());
                httpSession.setAttribute("M_EMAIL", member.getUemail());
                httpSession.setAttribute("M_NAME", member.getUname());
                httpSession.setAttribute("M_ROLE", member.getUrole());

                String url = (String)httpSession.getAttribute("BACKURL");
                return "redirect:" + url;
            }       
        return "redirect:/member/login";
    }

  • SecurityController.java
package com.example.controller;

import com.example.dto.MemberDTO;
import com.example.dto.MyUserDTO;
import com.example.mapper.MemberMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class SecurityController {

    @Autowired MemberMapper mMapper;

    @GetMapping(value = { "/security_home" })
    public String securityHomeGET(Model model, @AuthenticationPrincipal MyUserDTO user){
        if(user != null) {
            System.out.println(user.getUsername());
            System.out.println(user.getName());
            System.out.println(user.getUserphone());
            System.out.println(user.getAuthorities().toArray()[0]);
        }
        model.addAttribute("user", user);
        // model.addAttribute("userid", user.getUsername());
        // model.addAttribute("userrole", user.getAuthorities().toArray());

        return "/security/home";
    }

    // 로그인 후 보이는 페이지
    @GetMapping(value = { "/security_admin/home" })
    public String securityAdminHomeGET(){
        return "/security/admin_home";
    }
    
    // 로그인 후 보이는 페이지
    @GetMapping(value = { "/security_seller/home" })
    public String securitySellerHomeGET(){
        return "/security/seller_home";
    }

    // 로그인 후 보이는 페이지
    @GetMapping(value = { "/security_customer/home" })
    public String securityCustomerHomeGET(){
        return "/security/customer_home";
    }

    // 로그인 후 보이는 페이지
    @GetMapping(value = "/member/security_join")
    public String securityJoinGET() {
        return "/security/join";
    }

    @PostMapping(value = "/member/security_join")
    public String securityJoinPOST(@ModelAttribute MemberDTO member) {
        BCryptPasswordEncoder bcpe = new BCryptPasswordEncoder();
        // 암호를 가져와서 해시한 후 다시 추가하기
        member.setUpw(bcpe.encode(member.getUpw()));
        member.setUrole("CUSTOMER");

        int ret = mMapper.memberJoin(member);

        if(ret == 1) { // 성공
            return "redirect:/security_home";
        }
        // 실패
        return "redirect:/member/security_join";
    }

    @GetMapping(value = "/member/security_login")
    public String securityLoginGET() {
        return "/security/login";
    }

    @GetMapping(value = { "/security_403" })
    public String security403GET(){
        return "/security/403page";
    }
}

  • MyUserDTO.java
package com.example.dto;

import java.util.Collection;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = false)
public class MyUserDTO extends User{

    private static final long serialVersionUID = 1L;
    private String username = null;
    private String password = null;
    private String userphone = null;
    private String name = null;
    
    public MyUserDTO(
        String username, 
        String password, 
        Collection<? extends GrantedAuthority> authorities,
        String userphone,
        String name) {
        super(username, password, authorities);
        this.username = username;
        this.password = password;
        this.userphone = userphone;
        this.name = name;
    }
}

  • example/handler/MyLoginSuccessHandler.java
package com.example.handler;

import java.io.IOException;

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.AuthenticationSuccessHandler;

// 로그인이 성공했을 때 자동으로 호출되는 handler
public class MyLoginSuccessHandler 
    implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(
            HttpServletRequest request,
            HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        System.out.println("LoginSuccessHandler");

        User user = (User)authentication.getPrincipal();
        System.out.println(user.toString());

        String role = authentication.getAuthorities().toArray()[0].toString();
        System.out.println(role);

        // /ROOT
        System.out.println(request.getContextPath());

        if(role.equals("ADMIN")) {
            response.sendRedirect(request.getContextPath() + "/security_admin/home");
        }
        else if(role.equals("SELLER")) {
            response.sendRedirect(request.getContextPath() + "/security_seller/home");
        }
        else if(role.equals("CUSTOMER")) {
            response.sendRedirect(request.getContextPath() + "/security_customer/home");
        }
    }
}

  • example/handler/MyLogoutSuccessHandler.java
package com.example.handler;

import java.io.IOException;

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

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

public class MyLogoutSeccessHandler implements LogoutSuccessHandler{

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {
        response.sendRedirect(request.getContextPath() + "/security_home");
    }
    
}

  • MemberMapper.java(수정)
    @Select({ "SELECT UEMAIL, UPW, UROLE, UPHONE, UNAME FROM MEMBER WHERE UEMAIL = #{email}"})
    public MemberDTO memberEmail(
        @Param(value = "email") String em
    );

  • MemberDetailServiceImpl.java
package com.example.service;

import java.util.Collection;

import com.example.dto.MemberDTO;
import com.example.dto.MyUserDTO;
import com.example.mapper.MemberMapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class MemberDetailServiceImpl implements UserDetailsService{

    @Autowired MemberMapper mMapper;

    // 로그인에서 입력하는 정보 중에서 아이디를 받음
    // MemberMapper를 이용해서 정보를 가져와서 UserDetails로 리턴
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("MemberDetailService: " + username);
        MemberDTO member = mMapper.memberEmail(username);

        // 권한 정보를 문자열 배열로 만듦
        String[] strRole = { member.getUrole() };

        // String 배열 권한을 Collection<Granted...>로 변환함
        Collection<GrantedAuthority> roles = AuthorityUtils.createAuthorityList(strRole);

        // 아이디, 암호, 권한들이라서 컬렉션을 씀
        // User user = new User(member.getUemail(), member.getUpw(), roles);
        MyUserDTO user = new MyUserDTO(
            member.getUemail(), 
            member.getUpw(), 
            roles, 
            member.getUphone(), 
            member.getUname());
        return user;
    }
}

  • templage/security/403page.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>member/join</title>
    <link rel="stylesheet" type="text/css"
        th:href="@{/css/mystyle.css}" />
</head>
<body>
    <div style="padding:20px">
        <h3>접근 권한이 없습니다</h3>

        <a th:href="@{/security_home}">홈으로</a>
    </div>
</body>
</html>

  • templage/security/admin_home.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>member/join</title>
    <link rel="stylesheet" type="text/css"
        th:href="@{/css/mystyle.css}" />
</head>
<body>
    <div class="container" style="align-items: center;">
        <h3>관리자홈</h3>
        <a th:href="@{/member/security_login}">로그인</a>
        <a th:href="@{/member/security_join}">회원가입</a>
        <hr />
        <div style="display:inline-block">
            <a th:href="@{/security_admin/home}">관리자홈</a>
            <a th:href="@{/security_seller/home}">판매자홈</a>
            <a th:href="@{/security_customer/home}">고객홈</a>
        </div>
        <form th:action="@{/member/security_logout}" method="post">
            <input type="submit" value="로그아웃" />
        </form>

    </div>
</body>
</html>

  • templage/security/customer_home.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>member/join</title>
    <link rel="stylesheet" type="text/css"
        th:href="@{/css/mystyle.css}" />
</head>
<body>
    <div class="container" style="align-items: center;">
        <h3>고객홈</h3>
        <hr />
        <div style="display:inline-block">
            <!-- '@'의 역할 => context-path를 자동으로 잡아줌 -->
        </div>
    </div>
</body>
</html>

  • home.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>member/join</title>
    <link rel="stylesheet" type="text/css"
        th:href="@{/css/mystyle.css}" />
</head>
<body>
    <div style="padding:20px">
        <h3>/security/home.html 파일</h3>
        
        <hr />
        
		<hr />
        <div th:if="${user == null}">
            <h3>로그인 전</h3>
            <a th:href="@{member/security_login}">로그인</a>	
            <a th:href="@{member/security_join}">회원가입</a>    
        </div>
        <div th:if="${user != null}">
            <h3>로그인 후</h3>
            <form th:action="@{/member/security_logout}" method="post">
                <input type="submit" value="로그아웃" />
			</form>
            <a th:href="@{security_admin/home}">관리자홈</a>
            <a th:href="@{security_seller/home}">판매자홈</a>
            <a th:href="@{security_customer/home}">고객홈</a>
        </div>
    </div>
</body>
</html>

  • join.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>member/join</title>
    <link rel="stylesheet" type="text/css"
        th:href="@{/css/mystyle.css}" />
</head>
<body>
    <div class="container" style="align-items: center;">
        <h3>회원가입</h3>
        <hr />
        <div style="display:inline-block">
            <!-- '@'의 역할 => context-path를 자동으로 잡아줌 -->
            <form th:action="@{/member/security_join}" method="post">

                이메일: <input type="text" name="uemail" /><br />
                암호: <input type="password" name="upw" /><br />
                암호확인: <input type="password" /><br />
                이름: <input type="text" name="uname" /><br />
                연락처: <input type="text" name="uphone" /><br />
                <br />
                <input type="submit" value="회원가입" />
                <a th:href="@{/}"></a>
        
            </form>
        </div>
    </div>
</body>
</html>

  • login.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>member/login</title>
    <link rel="stylesheet" type="text/css"
        th:href="@{/css/mystyle.css}" />
</head>
<body>
    <div style="padding: 20px">
        <h3>로그인</h3>
        <hr />

        <!-- '@'의 역할 => context-path를 자동으로 잡아줌 -->
        <form th:action="@{/member/security_loginaction}" method="post">

        이메일: <input type="text" name="uemail" /><br />
        암호: <input type="password" name="upw" /><br />

        <input type="submit" value="로그인" />
    </form>
    </div>
</body>
</html>

  • seller_home.html
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>member/join</title>
    <link rel="stylesheet" type="text/css"
        th:href="@{/css/mystyle.css}" />
</head>
<body>
    <div class="container" style="align-items: center;">
        <h3>판매자홈</h3>
        <hr />
        <div style="display:inline-block">
            <!-- '@'의 역할 => context-path를 자동으로 잡아줌 -->
        </div>
    </div>
</body>
</html>

0개의 댓글