> Hello World !!!

     

@syaku

스프링 시큐리티 로그인 커스텀 #2 : Spring Framework Security Login Custom 스프링프레임워크 #2

written by Seok Kyun. Choi. 최석균

스프링 시큐리티 로그인 커스텀 #2

스프링 시큐리티 연재 포스팅
2014/08/29 - [개발노트/Spring] - 스프링 시큐리티 로그인 #1 : Spring Framework Security Login 스프링프레임워크 #1
2014/09/04 - [개발노트/Spring] - 스프링 시큐리티 로그인 커스텀 #2 : Spring Framework Security Login Custom 스프링프레임워크 #2
2014/09/04 - [개발노트/Spring] - 스프링 시큐리티 로그인 Handler Ajax #3 : Spring Framework Security Login Ajax 스프링프레임워크 #3
2014/10/25 - [개발노트/Spring] - 스프링 시큐리티 커스텀 로그인 : Spring Security Custom Login UserDetailsService AuthenticationProvider #4 스프링프레임워크/Spring Framework

개발환경

Mac OS X 10.9.4
JAVA 1.6
Apache Tomcat 7.x
Spring 3.1.1
Spring Tool Suite 3.5.1
Maven 2.5.1

jQuery 1.11.1

이번에는 로그인 페이지를 직접 개발하는 방법을 알아보자.

@소스 pom.xml

<!-- Spring Security -->
<dependency>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-web</artifactId>
     <version>${org.springframework-version}</version>
</dependency>
<dependency>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-config</artifactId>
     <version>${org.springframework-version}</version>
</dependency>

<!— CGLib —>
<dependency>
     <groupId>cglib</groupId>
     <artifactId>cglib</artifactId>
     <version>3.1</version>
     <type>jar</type>
     <scope>compile</scope>
</dependency>

스프링 시큐리티 설정 파일을 열어 아래와 같이 수정한다.

@소스 security-context.xml

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

     <http auto-config="true" use-expressions="true" access-denied-page="/denied">

     <form-login
     login-page="/signin"
     username-parameter="user_id"
     password-parameter="password"
     authentication-failure-url="/signin?error=true"
     default-target-url="/mypage"
     always-use-default-target="false"
     />

     <logout
     invalidate-session="true"
     logout-success-url="/signin"
     logout-url="/signout" />

     </http>

     <authentication-manager>
          <authentication-provider>
               <password-encoder ref="passwordEncoder"/>
               <user-service>
                    <user name="guest" password="35675e68f4b5af7b995d9205ad0fc43842f16450" authorities="ROLE_USER"/>
                    <user name="admin" password="d033e22ae348aeb5660fc2140aec35850c4da997" authorities="ROLE_ADMIN"/>
               </user-service>
          </authentication-provider>
     </authentication-manager>

     <beans:bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" id="passwordEncoder" />

</beans:beans>

기존에 있던 http 설정을 위와 같이 로그인 페이지를 각각 설정할 수 있다.

HTTP 설정 정보
access-denied-page : 접속 권한이 없을 경우 호출되는 페이지

FORM LOGIN 설정 정보

역활 설명
login-page 로그인 페이지, 세션 인증이 없는 경우 호출될 URL (기본 URL : j_spring_security_login)
username-parameter 로그인 페이지에서 사용될 사용자 계정 파라메터명
password-parameter 로그인 페이지에서 사용될 사용자 암호 파라메터명
login-processing-url 로그인 처리를 호출할때 사용 할 URL. 보여지는 URL 일뿐 j_spring_security_check 호출되어 로그인 처리한다.
authentication-failure-url 로그인을 실패했을 때 호출될 URL
default-target-url 로그인 후 호출될 URL
always-use-default-target 로그인 후 항상 default-target-url 호출할 것인 지 여부. false 인 경우 로그인 페이지 이전화면을 호출한다.
authentication-success-handler-ref 로그인 후 호출될 핸들러. 직접 후처리를 작업할 경우 사용
authentication-failure-handler-ref 로그인 실패 후 호출될 핸들러. 직접 후처리를 작업할 경우 사용
authentication-details-source-ref -

LOGOUT 설정 정보

역활 설명
invalidate-session 세션 삭제 여부
logout-success-url 로그아웃 후 호출될 URL
logout-url 로그아웃 처리를 요청할때 사용할 URL. 보여지는 URL 일뿐 j_spring_security_logout 호출되어 로그아웃을 처리한다.
delete-cookies 삭제할 쿠키명을 입력한다.

password-encoder 를 추가하여 비밀번호를 암호화하였다. 그래서 계정의 비밀번호도 암호화된 값을 입력해야 한다.

<password-encoder hash="sha"/> 암호화를 설정할 수도 있다. 암호화 값은 아래와 같다.

Implementation class Description hash value
PlaintextPasswordEncoder Encodes the passwordas plaintext. Default DaoAuthenticationProvider password encoder. plaintext
Md4PasswordEncoder PasswordEncoder utilizing the MD4 hash algorithm. MD4 is not a secure algorithm-use of this encoder is not recommended. md4
Md5PasswordEncoder PasswordEncoder utilizing the MD5 one-way encoding algorithm. md5
ShaPasswordEncoder PasswordEncoder utilizing the SHA one-way encoding algorithm. This encoder can support confi gurable levels of encoding strength. Sha sha-256
LdapShaPasswordEncoder Implementation of LDAP SHA and LDAP SSHA algorithms used in integration with LDAP authentication stores. {sha} {ssha}

이제 각 뷰페이지와 컨트롤러를 생성한다.

@소스 servlet-context.xml

<?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
     http://www.springframework.org/schema/mvc/spring-mvc.xsd
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context.xsd
     http://www.springframework.org/schema/security
     http://www.springframework.org/schema/security/spring-security.xsd
     ">

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

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

     <security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled" />

     <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
     <resources mapping="/resources/**" location="/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="com.syaku.security" />
</beans:beans>

스프링 설정 파일은 이전 소스와 다르지 않다.

@소스 SignController.java

package com.syaku.security;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class SignController {
     private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

     @Autowired
     private PasswordEncoder passwordEncoder;

     @RequestMapping(value="/signin", method = RequestMethod.GET)
     public String signin(@RequestParam(value="error", required=false) String error, Model model) {

          model.addAttribute("error", error);

          // Sha 암호값을 보기 위한 테스트용.
          String guest_password = passwordEncoder.encodePassword("guest", null);
          String admin_password = passwordEncoder.encodePassword("admin", null);

          logger.info(guest_password + "//" + admin_password);

          return "signin";
     }

     @PreAuthorize("authenticated")
     @RequestMapping(value="/mypage", method = RequestMethod.GET)
     public String mypage(Model model) {

          Authentication auth = SecurityContextHolder.getContext().getAuthentication();
          model.addAttribute("user_name", auth.getName());

          return "mypage";
     }


     @RequestMapping(value="/denied", method = RequestMethod.GET)
     public String denied() {
          return "denied";
     }

}

@소스 signin.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html>
<html lang="ko">
     <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>Spring security</title>

     <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
     <script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
     </head>

     <body>

     <c:if test="${error == 'true'}">
     <script>
     jQuery(function() {
          var move = '70px';
          jQuery('#message').animate({
               top : '+=' + move
          }, 'slow', function() {
               jQuery('#message').delay(1000).animate({ top : '-=' + move }, 'slow');
          });
     });
     </script>
     </c:if>

     <div>
     <div id="message" style="width:300px;position:absolute; top:-60px;border: 1px;border-color: #000;">로그인에 실패하셨습니다.</div>
     </div>

     <div style="margin-top:100px;">
     <form action="./j_spring_security_check" method="post">
     아이디 : <input type="text" id="user_id" name="user_id">
     비밀번호 : <input type="password" id="password" name="password">
     <button type="submit">Sign in</button>
     </form>

     </div>

     </body>

</html>

@소스 mypage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html>
<html lang="ko">
     <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>Spring security</title>

     <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
     <script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
     </head>

     <body>

     <h1>${user_name} 로그인 성공!!</h1>

     </body>

</html>

@소스 denied.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html>
<html lang="ko">
     <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>Spring security</title>
     <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
     <script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
     </head>

     <body>

     <h1>권한이 없습니다.</h1>

     </body>

</html>

권한이 없는 경로를 접근할 경우 /denied 호출되게 된다.

posted syaku blog

Syaku Blog by Seok Kyun. Choi. 최석균.

http://syaku.tistory.com