๐Ÿ”ฅ #8 ๋กœ๊ทธ์ธ์— ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ ์ ์šฉํ•˜๊ธฐ

myeonjiยท2022๋…„ 2์›” 20์ผ
0

์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด,
์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํˆด๋กœ WebSecurityConfigurerAdapter๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
ํ•ด๋‹น ํˆด์„ ์ƒ์†๋ฐ›๋Š” SecurityConfig๋ผ๋Š” ์„ค์ •ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

์ด ์„ค์ •ํŒŒ์ผ์—์„œ๋Š” ์–ด๋””๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ํ™•์ธํ• ์ง€, ํ•ด์‰ฌ๋Š” ๋ญ˜๋กœ ํ• ์ง€, ์œ ์ € ์•„์ด๋””๋Š” ์–ด๋””์„œ ์ฐพ์„์ง€ ๋“ฑ์„ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ์„ค์ •์„ ๋ฐ”ํƒ•์œผ๋กœ ์œ ์ € ๊ฐ์ฒด๋Š” PrincipalDetailService๋กœ ์ฐพ๊ณ , ํ•ด์‰ฌ๋Š” Bcrypt๋กœ ํ‘ธ๋Š” ๋“ฑ ๊ตฌํ˜„์„ ํ•œ๋‹ค.
๋˜ํ•œ ์‹œํ๋ฆฌํ‹ฐ ์„ธ์…˜์—๋Š” UserDetails ๋ฐ–์— ์ €์žฅํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ๋„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.


๋กœ๊ทธ์ธ ์ฃผ์†Œ, ๋กœ๊ทธ์•„์›ƒ ์ฃผ์†Œ ๋งคํ•‘์ด ํ”„๋ ˆ์ž„์›Œํฌ ์‹œํ๋ฆฌํ‹ฐ์— ์ด๋ฏธ ํ•„ํ„ฐ๋กœ ๋งŒ๋“ค์–ด์ ธ ์žˆ๋‹ค.

  • ๋กœ๊ทธ์•„์›ƒ ํ•„ํ„ฐ
  • username password ์ธ์ฆ ํ•„ํ„ฐ

์ฃผ์†Œ ์„ธํŒ…

  • ์ธ์ฆ์ด ์•ˆ๋œ ์‚ฌ์šฉ์ž๋“ค์ด ์ถœ์ž…ํ•  ์ˆ˜ ์žˆ๋Š”(ํ—ˆ์šฉ๋˜๋Š”) ๊ฒฝ๋กœ
    • /auth/**
    • /
    • static ์ดํ•˜์— ์žˆ๋Š” /js/**, /css/**, /image/**

/ (์ปจํ…์ŠคํŠธ ์‚ญ์ œ) -> index.jsp

< UserApiController >
/auth/joinProc
/auth/loginProc

< UserController >
/auth/joinForm
/auth/loginForm

๊ทธ ์™ธ : auth ๋ถ™์ด๋ฉด ์•ˆ๋˜๋Š” ์ฃผ์†Œ (์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๋งŒ ํ—ˆ์šฉ๋˜๋Š” ์ฃผ์†Œ)
๊ธ€์“ฐ๊ธฐ : /board/form
ํšŒ์›์ •๋ณด : /user/form
๋กœ๊ทธ์•„์›ƒ : /logout


ํŒŒ์ผ ์ˆ˜์ •

< loginForm.jsp >

๋กœ๊ทธ์ธ์„ form ํƒœ๊ทธ (x-www-form-urlencoded ํƒ€์ž…๋ฐ์ดํ„ฐ) ๋กœ ํ•˜๋Š” ์ด์œ  : ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ x-www-form-urlencoded ํƒ€์ž…๋ฐ์ดํ„ฐ ๋งŒ ํŒŒ์‹ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

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

<%@ include file="../layout/header.jsp"%>

<div class="container">

    <form action="/auth/loginProc" method="post">
    
        <div class="form-group">
            <label for="username">Username</label>
            <input type="text" name="username" class="form-control" placeholder="Enter username" id="username">
        </div>
        
        <div class="form-group">
            <label for="password">Password</label>
            <input type="password" name="password" class="form-control" placeholder="Enter password" id="password">
        </div>
        
        <button id="btn-login" class="btn btn-primary">๋กœ๊ทธ์ธ</button>
        
    </form>
</div>

<!-- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  form์—์„œ ์•ก์…˜ ํƒ€์„œ ๋ณด๋‚ผ๊ฑฐ๋ผ ์•„๋ž˜ ๋ฌธ์žฅ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ-->
<!--<script src="/js/user.js"><</script>-->
<%@ include file="../layout/footer.jsp"%>
  • user.js ์‚ฌ์šฉํ•˜์ง€ ์•Š์„๊ฑฐ๋ผ ์ง€์šฐ๊ณ , input type์— name ์†์„ฑ ๋„ฃ๊ธฐ

< user.js >

let index = {
    init: function () {
        $("#btn-save").on("click", ()=>{ // function(){} ๋Œ€์‹  ()=>{} ๋ฅผ ์“ด ์ด์œ  : this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ ์œ„ํ•ด์„œ
            this.save();
        });
        //$("#btn-login").on("click", ()=>{ // function(){} ๋Œ€์‹  ()=>{} ๋ฅผ ์“ด ์ด์œ  : this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ ์œ„ํ•ด์„œ
        //    this.login();
        //});
    },

    save: function () {
        // alert('user์˜ saveํ•จ์ˆ˜ ํ˜ธ์ถœ๋จ');
        let data = {
            username: $("#username").val(),
            password: $("#password").val(),
            email: $("#email").val()
        };

        // console.log(data); data๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์˜ค๋ธŒ์ ํŠธ
        // console.log(JSON.stringify(data)); JSON ๋ฌธ์ž์—ด

        // ajax ํ˜ธ์ถœ์‹œ default๊ฐ€ ๋น„๋™๊ธฐ ํ˜ธ์ถœ -> ์ˆœ์„œ ์ƒ๊ด€์—†์Œ
        // ajax ํ†ต์‹ ์„ ์ด์šฉํ•ด์„œ 3๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ json์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ insert ์š”์ฒญ
        // ajax๊ฐ€ ํ†ต์‹ ์„ ์„ฑ๊ณตํ•˜๊ณ  ์„œ๋ฒ„๊ฐ€ json์„ ๋ฆฌํ„ดํ•ด์ฃผ๋ฉด ์ž๋™์œผ๋กœ ์ž๋ฐ”(์Šคํฌ๋ฆฝํŠธ?) ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณ€ํ™˜
        $.ajax({
            // ํšŒ์›๊ฐ€์ž… ์ˆ˜ํ–‰ ์š”์ฒญ
            type: "POST",
            url: "/auth/joinProc",
            data: JSON.stringify(data), // http body ๋ฐ์ดํ„ฐ
            contentType: "application/json; charset=utf-8", // body ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ (MIME)
            dataType: "json" // ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ํ•ด์„œ ์‘๋‹ต์ด ์™”์„ ๋•Œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ๊ฒƒ์ด String(๋ฌธ์ž์—ด), ๋งŒ์•ฝ ์ƒ๊ธด๊ฒŒ json์ด๋ผ๋ฉด javascript ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณ€๊ฒฝ
        }).done(function (resp) {
            // ๊ฒฐ๊ณผ๊ฐ€ ์ •์ƒ์ด๋ฉด done ์‹คํ–‰
            alert("ํšŒ์›๊ฐ€์ž…์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
            //console.log(resp);
            location.href = "/";
        }).fail(function (error) {
            // ์‹คํŒจํ•˜๋ฉด fail ์‹คํ–‰
            alert("ํšŒ์›๊ฐ€์ž…์ด ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค.");
            alert(JSON.stringify(error));
        });
    },

    /*
    login: function () {
        let data = {
            username: $("#username").val(),
            password: $("#password").val()
        };

        $.ajax({
            type: "POST",
            url: "/api/user/login",
            data: JSON.stringify(data), // http body ๋ฐ์ดํ„ฐ
            contentType: "application/json; charset=utf-8", // body ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ (MIME)
            dataType: "json" // ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ํ•ด์„œ ์‘๋‹ต์ด ์™”์„ ๋•Œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ๊ฒƒ์ด String(๋ฌธ์ž์—ด), ๋งŒ์•ฝ ์ƒ๊ธด๊ฒŒ json์ด๋ผ๋ฉด javascript ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณ€๊ฒฝ
        }).done(function (resp) {
            // ๊ฒฐ๊ณผ๊ฐ€ ์ •์ƒ์ด๋ฉด done ์‹คํ–‰
            alert("๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
            //console.log(resp);
            location.href = "/";
        }).fail(function (error) {
            // ์‹คํŒจํ•˜๋ฉด fail ์‹คํ–‰
            alert("๋กœ๊ทธ์ธ์ด ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค.");
            alert(JSON.stringify(error));
        });
    }
     */
}


index.init();
  • ๋กœ๊ทธ์ธ์— ํ•ด๋‹นํ•˜๋Š” ๋ถ€๋ถ„ ์ „๋ถ€ ์ง€์šฐ๊ธฐ

๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

< SecurityConfig >

  • ๋นˆ ๋“ฑ๋ก : ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ
  • ์•„๋ž˜ ์„ธ ๊ฐœ์˜ ์–ด๋…ธํ…Œ์ด์…˜์€ ์‹œํ๋ฆฌํ‹ฐ์—์„œ ์„ธํŠธ๋กœ ์‚ฌ์šฉ
@Configuration // ๋นˆ ๋“ฑ๋ก (IoC๊ด€๋ฆฌ)
@EnableWebSecurity // Security ํ•„ํ„ฐ๊ฐ€ ๋“ฑ๋ก๋จ = ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ์ด๋ฏธ ํ™œ์„ฑํ™”๋Š” ๋˜์–ด์žˆ์ง€๋งŒ, ์„ค์ •์€ ํ•ด๋‹น ํŒŒ์ผ์—์„œ ํ•  ๊ฒƒ์ž„
@EnableGlobalMethodSecurity(prePostEnabled = true) // ํŠน์ • ์ฃผ์†Œ๋กœ ์ ‘๊ทผ์„ ํ•˜๋ฉด ๊ถŒํ•œ ๋ฐ ์ธ์ฆ์„ ๋ฏธ๋ฆฌ ์ฒดํฌ

// ๋นˆ ๋“ฑ๋ก : ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ
// ์•„๋ž˜ 3๊ฐœ์˜ ์–ด๋…ธํ…Œ์ด์…˜์€ ์‹œํ๋ฆฌํ‹ฐ์—์„œ ์„ธํŠธ๋กœ ์‚ฌ์šฉ

@Configuration // ๋นˆ ๋“ฑ๋ก (IoC๊ด€๋ฆฌ)
@EnableWebSecurity // Security ํ•„ํ„ฐ๊ฐ€ ๋“ฑ๋ก๋จ = ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๊ฐ€ ์ด๋ฏธ ํ™œ์„ฑํ™”๋Š” ๋˜์–ด์žˆ์ง€๋งŒ, ์„ค์ •์€ ํ•ด๋‹น ํŒŒ์ผ์—์„œ ํ•  ๊ฒƒ์ž„
@EnableGlobalMethodSecurity(prePostEnabled = true) // ํŠน์ • ์ฃผ์†Œ๋กœ ์ ‘๊ทผ์„ ํ•˜๋ฉด ๊ถŒํ•œ ๋ฐ ์ธ์ฆ์„ ๋ฏธ๋ฆฌ ์ฒดํฌ (์ˆ˜ํ–‰ํ•œ ํ›„์— ์ฒดํฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹˜)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // ํ•„ํ„ฐ๋ง
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        		.csrf().disable() // csrf ํ† ํฐ ๋น„ํ™œ์„ฑํ™” (ํ…Œ์ŠคํŠธ์‹œ ๊ฑธ์–ด๋‘๋Š”๊ฒŒ ์ข‹์Œ)
                .authorizeRequests() // request๊ฐ€ ๋“ค์–ด์˜ค๋ฉด
                .antMatchers("/", "/auth/**", "/js/**", "/css/**", "/image/**") // ์—ฌ๊ธฐ๋กœ ๋“ค์–ด์˜ค๋ฉด
                .permitAll() // ๋ชจ๋‘ ๊ฐ€๋Šฅ (๋ˆ„๊ตฌ๋‚˜ ๊ฐ€๋Šฅ)
                .anyRequest() // ๊ทธ๊ฒŒ ์•„๋‹Œ ๋‹ค๋ฅธ ๋ชจ๋“  ์š”์ฒญ์€
                .authenticated() // ์ธ์ฆ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค
                .and()
                .formLogin()
                .loginPage("/auth/loginForm"); // ์ธ์ฆ์ด ํ•„์š”ํ•œ ์š”์ฒญ์€ ์ด ๋กœ๊ทธ์ธ ํผ์œผ๋กœ ์˜จ๋‹ค
    }

    // ์ฐธ๊ณ  : .headers().frameOptions().disable() // ์•„์ดํ”„๋ ˆ์ž„ ์ ‘๊ทผ ๋ง‰๊ธฐ
    // ์ฐธ๊ณ  : .csrf().disable() // csrf ํ† ํฐ ๋น„ํ™œ์„ฑํ™” (ํ…Œ์ŠคํŠธ์‹œ ๊ฑธ์–ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Œ)
}
  • ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํˆด๋กœ WebSecurityConfigurerAdapter ๋ฅผ ์ƒ์†๋ฐ›๊ธฐ

์—ฌ๊ธฐ๊นŒ์ง€ ํ•˜๊ณ  ํšŒ์›๊ฐ€์ž… ํ•  ๋•Œ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•ด์‰ฌํ•˜๋Ÿฌ ๊ณ ๊ณ 

profile
๐Ÿ“š

0๊ฐœ์˜ ๋Œ“๊ธ€