관리 메뉴

bright jazz music

스프링 시큐리티 설정 본문

Framework/Spring Security

스프링 시큐리티 설정

bright jazz music 2022. 9. 13. 18:48

진행 중

 

 

SecurityConfig.java

//SecurityConfig.java

package com.example.common;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration //설정파일이므로
@EnableWebSecurity //여러 클래스들을 임포트 해서 실행시키는  어노테이션이다. 그래야 웹 보안이 활성화 된다.


public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                "/**"
                //static 밑으로 전부 허용
                //"/adminLTE/**", "/document/", "/img", "/js", "/se"
                );
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http
                .authorizeRequests()    //요청에 대한 보안검사 시작
                .anyRequest().authenticated(); //어떤 요청에도 인가 받도록 설정. 안 받으면 접근 불가
        //그래서 인가를 받기 위해 /loginPage로 이동한다. 근데 이 경로도 인가가 필요하다.
        //그래서 이 경로는 인가를 받지 않아도 접근 가능하도록 처리한다.
        // .permitALL()을 붙여줘서 /loginPage로의 접근은 인가르 받지 않아도 되도록 처리한다.

        http
                .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

        //이제 인증방식
        http
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/")
                .failureUrl("/login")
//                .usernameParameter("userId")
//                .passwordParameter("passwd")
                .loginProcessingUrl("/login")
                .successHandler(new AuthenticationSuccessHandler() { //로그인에 성공했을 떄 성공 핸들러. AuthenticationSuccessHander 구현체를 넣어주면 된다. 우리는 걍 익명 클래스 사용
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        //request, response, authentication 인증에 성공했을 때 그 결과를 담은 인증 객체까지 파라미터로 전달되어서 넘어온다.
                        //이걸 활요해서 구체적인 로직을 구현하면 된다.
                        System.out.println("authentication : " + authentication.getName());
                        response.sendRedirect("/"); //루트페이지로 이동
                    }
                })
                //실패하면 아래의 실패 핸들러 호출
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
                        //인증 예외 객체를 파라미터로 전달 받는다.
                        System.out.println("exception : " + exception.getMessage()); //예외 메시지 출력
                        response.sendRedirect("/login");
                    }
                })
                .permitAll();

//        http
//                .logout()
//                .logoutUrl("/logout") //기본값은 /logout. 그리고 스프링 시큐리티는 기본적으로 POST방식으로 로그아웃 한다. 따라서 GET을 쓰면 오류난다. 그러나 GET으로 할 수 있는 방법도 있다.
//                .logoutSuccessHandler("/logout")
//                .addLogoutHandler()

    }


}

 

(로그인) form.jsp

<!-- form.jsp -->

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>

    <div class="login-box">
        <c:if test="${sessionedErorrMessage != null }">
            <script type="text/javascript">
                var message = '${sessionedErorrMessage }';
                alert(message);
            </script>
        </c:if>

        <!-- request로 넘어온 오류 메시지  -->
        <c:if test="${errorMessage != null}">
            <div class="modal fade in" id="modal-default" style="display: block;">
              <div class="modal-dialog">
                <div class="modal-content">
                  <div class="modal-header">
                    <button type="button" class="close" >
                      <span aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title">메시지</h4>
                  </div>
                  <div class="modal-body">
                    <p>${errorMessage}</p>
                  </div>
                  <div class="modal-footer">
                    <button type="button" class="btn btn-default" >Close</button>
                  </div>
                </div>
                <!-- /.modal-content -->
              </div>
              <!-- /.modal-dialog -->
            </div>
            <script type="text/javascript">
                // modal창 닫기 
                $("button.btn").on("click", function(e){
                    $("#modal-default").hide();
                    e.stopPropagation();
                });
                $("button.close").on("click", function(e){
                    $("#modal-default").hide();
                    e.stopPropagation();
                });
            </script>
        </c:if>

        <c:if test="${sessionedMessage != null}">
            <div class="modal fade in" id="modal-default" style="display: block;">
                  <div class="modal-dialog">
                    <div class="modal-content">
                      <div class="modal-header">
                        <button type="button" class="close" >
                          <span aria-hidden="true">&times;</span></button>
                        <h4 class="modal-title">알림 메시지</h4>
                      </div>
                      <div class="modal-body">
                        <p>${sessionedMessage}</p>
                      </div>
                      <div class="modal-footer">
                        <button type="button" class="btn btn-default" >Close</button>
                      </div>
                    </div>
                    <!-- /.modal-content -->
                  </div>
                  <!-- /.modal-dialog -->
                </div>
                <script type="text/javascript">
                    // modal창 닫기 
                    $("button.btn").on("click", function(e){
                        $("#modal-default").hide();
                        e.stopPropagation();
                    });
                    $("button.close").on("click", function(e){
                        $("#modal-default").hide();
                        e.stopPropagation();
                    });
                </script>
        </c:if>

        <div class="login-logo">
            <a href="#"><b>example project</b> management</a>
        </div>
        <!-- /.login-logo -->
        <div class="login-box-body">
            <p class="login-box-msg">관리자 로그인</p>
            <form:form id="loginForm" method="POST" action="/login" commandName="loginVO">
            
            <!-- CSRF -->
                <input type="hidden" name="_csrf" value="{{#_csrf}}token{{/_csrf}}" />
                
                <div class="form-group has-feedback">
                    <form:input path="adminId" cssClass="form-control" placeholder="아이디" />
                    <span class="glyphicon glyphicon-envelope form-control-feedback"></span>
                    <form:errors path="adminId" cssClass="error" />
                </div>
                <div class="form-group has-feedback">
                    <form:password path="adminPwd" cssClass="form-control" placeholder="비밀번호" />
                    <span class="glyphicon glyphicon-lock form-control-feedback"></span>
                    <form:errors path="adminPwd" cssClass="error" />
                </div>
                <div class="row">
                    <div class="col-xs-12">
                        <input type="checkbox" id="saveCheck" name="saveCheck" value="saveOk"><span class="pad"> ID 저장</span>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-12">
                        <button type="submit" id="loginBtn" class="btn btn-primary btn-block btn-flat">로그인</button>
                    </div>
                </div>
                <c:if test="${firstLogin }">
                   <div class="row">
                       <div class="col-xs-12">
                           <a href="<c:url value='/firstAdd/form'/>" class="btn btn-default" style="display:block;border-radius:0;">최초관리자등록</a>
                       </div>
                   </div>
                </c:if>
            </form:form>
        </div>
        <!-- /.login-box-body -->
    </div>
    <!-- /.login-box -->

<script type="text/javascript">
      $(document).ready(function () {
          var id = getCookie("id");
          var setYn = getCookie("setYn");
          
          if(setYn == 'Y') {
              $("#saveCheck").prop("checked", true);
          } else {
              $("#saveCheck").prop("checked", false);
          }
          
          $("#adminId").val(id); 
      })
   
      //쿠키값 Set
      function setCookie(cookieName, value, exdays){
          var exdate = new Date();
          exdate.setDate(exdate.getDate() + exdays);
          var cookieValue = escape(value) + ((exdays==null) ? "" : "; expires=" + 
          exdate.toGMTString());
          document.cookie = cookieName + "=" + cookieValue;
      }
   
      //쿠키값 가져오기
      function getCookie(cookie_name) {
          var x, y;
          var val = document.cookie.split(';');
          
          for (var i = 0; i < val.length; i++) {
              x = val[i].substr(0, val[i].indexOf('='));
              y = val[i].substr(val[i].indexOf('=') + 1);
              x = x.replace(/^\s+|\s+$/g, ''); 
              
              if (x == cookie_name) {
                return unescape(y); 
              }
          }
      }

      //쿠키값 Delete
      function deleteCookie(cookieName){
          var expireDate = new Date();
          expireDate.setDate(expireDate.getDate() - 1);
          document.cookie = cookieName + "= " + "; expires=" + expireDate.toGMTString();
      }

       $.validator.setDefaults({
           onkeyup:false,
           onclick:false,
           onfocusout:false,
           showErrors:function(errorMap, errorList){
               if(this.numberOfInvalids()) {
                   alert(errorList[0].message);
               }
           }
       });
         
      $("#loginForm").validate({
          rules: {
             // form태그의 path attribute 사용 
             "adminId" : {
                required : true
             },
             "adminPwd" : {
                required : true
             }
          },
          messages: {
             "adminId": {
                   required: "아이디를 입력해주세요."
               },
               "adminPwd": {
                   required: "비밀번호를 입력해주세요."
               }
          }
      })
   
   $('#loginBtn').click(function() {
         
        if($("#saveCheck").is(":checked")){ 
            var id = $("#adminId").val();
            setCookie("id", id, 30); 
            setCookie("setYn", "Y", 30);

        } else {
            deleteCookie("id");
            deleteCookie("setYn");
        }
});

</script>
Comments