스프링 시큐리티 로그인 커스텀 #2 : Spring Framework Security Login Custom 스프링프레임워크 #2
2014. 9. 4. 18:44 개발노트/Spring /279
스프링 시큐리티 로그인 커스텀 #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.1jQuery 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
호출되게 된다.