티스토리 뷰
Spring Security 도입하기.
프로젝트를 진행함에 있어 인증, 권한에 대한 이슈는 항상 존재하기 마련이다.
복잡한 권한관리를 Spring Security를 이용하면 간단히 해결 할 수 있다.
개발환경
Spring Framework 3.2
Maven 3.0.4
Hibernate 4.3.10
Spring Security 3.2.7
step 1. Spring Security Dependency 추가
spring security를 사용하기 위해 Dependency를 추가한다.
pom.xml
<!-- Security --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>3.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>3.2.7.RELEASE</version> </dependency>
step 2. Authentication 구현
로그인 처리로직을 위한 Provider를 생성한다. DB등의 Table에서 사용자 조회 후
인증에 성공한 경우 권한을 추가하면 된다.
CustomAuthenticationProvider.java
package kr.co.rocksea; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; public class CustomAuthenticationProvider implements AuthenticationProvider { private static final Logger logger = LoggerFactory.getLogger(LoginController.class); @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { String user_id = (String)authentication.getPrincipal(); String user_pw = (String)authentication.getCredentials(); logger.info("사용자가 입력한 로그인정보입니다. {}", user_id + "/" + user_pw); if(user_id.equals("test") && user_pw.equals("test")){ logger.info("로그인 성공."); List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>(); roles.add(new SimpleGrantedAuthority("ROLE_USER")); UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(user_id, user_pw, roles); result.setDetails(new CustomUserDetails(user_id, user_pw)); return result; }else{ logger.info("사용자 정보가 일치하지 않습니다."); throw new BadCredentialsException("Bad credentials"); } } }
CustomUserDetails.java
package kr.co.rocksea; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; public class CustomUserDetails implements UserDetails { private static final long serialVersionUID = -4450269958885980297L; private String username; private String password; public CustomUserDetails(String userName, String password) { this.username = userName; this.password = password; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); authorities.add(new SimpleGrantedAuthority("ROLE_USER")); return authorities; } @Override public String getPassword() { return password; } @Override public String getUsername() { return username; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
LoginController.java
package kr.co.rocksea; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class LoginController { private static final Logger logger = LoggerFactory.getLogger(LoginController.class); /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "login", method = RequestMethod.GET) public void login(HttpSession session) { logger.info("Welcome login. {}", session.getId()); } @RequestMapping(value = "logout", method = RequestMethod.GET) public void logout(HttpSession session) { CustomUserDetails userDetails = (CustomUserDetails)session.getAttribute("userLoginInfo"); logger.info("success logout. {}, {}", session.getId(), userDetails.getUsername()); session.invalidate(); } @RequestMapping(value = "login_success", method = RequestMethod.GET) public void login_success(HttpSession session) { CustomUserDetails userDetails = (CustomUserDetails)SecurityContextHolder.getContext().getAuthentication().getDetails(); logger.info("login success. {}, {}", session.getId(), userDetails.getUsername() + "/" + userDetails.getPassword()); session.setAttribute("userLoginInfo", userDetails); } @RequestMapping(value = "login_duplicate", method = RequestMethod.GET) public void login_duplicate() { logger.info("login_duplicate."); } }
login.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ page session="false" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%> <html> <head> <title>로그인페이지</title> </head> <body> <h2>로그인 </h2> <form name="form" method="post" action="loginProcess"> <table> <tr height="40px"> <td>사용자아이디</td> <td><input type="text" name="id"></td> </tr> <tr height="40px"> <td>패스워드</td> <td><input type="password" name="pw"></td> </tr> </table> <table> <tr> <td align="center"><input type="submit" value="로그인"></td> <td align="center"><input type="reset" value="리셋"></td> </tr> </table> </form> </body> </html>
step 3. Security 권한 설정
각 접근 URL Pattern에 맞게 권한을 설정 할 수 있다. 기본정책을 로그인이 필요한
ROLE_USER로(일반사용자)로 설정해두고 몇몇 URL만 로그인 안된 상태로
접근가능한 IS_AUTHENTICATED_ANONYMOUSLY(익명 사용자)로 설정하여
관리 할 수 있다.
기본적으로 Spring Security에서 지원하는 권한은 다음과 같다.
Authority |
Description |
ROLE_ANONYMOUS |
모든 사용자 |
IS_AUTHENTICATED_ANONYMOUSLY |
익명 사용자 |
IS_AUTHENTICATED_FULLY |
인증된 사용자 |
IS_AUTHENTICATED_REMEMBERED |
REMEMBERED 사용자 |
ROLE_RESTRICTED |
제한된 사용자 |
ROLE_USER |
일반 사용자 |
ROLE_ADMIN |
관리자 |
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" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <http auto-config='true' > <intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/login_duplicate" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/**" access="ROLE_USER" /> <form-login login-page="/login" username-parameter="id" password-parameter="pw" login-processing-url="/loginProcess" default-target-url="/login_success" authentication-failure-url="/login" always-use-default-target='true' /> <session-management> <concurrency-control max-sessions="1" expired-url="/login_duplicate"/> </session-management> </http> <beans:bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/> <authentication-manager> <authentication-provider ref="customAuthenticationProvider"/> </authentication-manager> <beans:bean id="customAuthenticationProvider" class="com.security.rocksea.CustomAuthenticationProvider"/> </beans:beans>
step 4. 기타 환경 설정
security-context 파일 경로 추가 및 Listener, Filter를 설정한다.
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:spring/application-config.xml classpath:spring/security-context.xml </param-value> </context-param> <!-- Spring Session Listener --> <listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener> <!-- Spring Security filter --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
step 5. 결과화면
[그림 1] 로그인 화면
[그림 2] 로그인 성공 화면
2. http://www.mkyong.com/spring-security/spring-security-hello-world-example/
'Developer' 카테고리의 다른 글
[ORM#2] Getting started with JPA (0) | 2015.08.04 |
---|---|
[Redis] How to use Transaction (2) | 2015.07.27 |
[ORM#1] Getting started with Hibernate (0) | 2015.07.23 |
[SpringFramework] How to use JSON-RPC (0) | 2015.07.22 |
[Django#3] Getting started with simple application (2) | 2015.07.10 |
- Total
- Today
- Yesterday
- maven
- 대명사 구문
- 영문법
- Python
- 영작
- NGINX
- 스페인 여행
- 가정법
- k8s
- PostgreSQL
- 도덕경
- hadoop
- 베트남
- AWS
- it
- nodejs
- hdfs
- memcached
- mongoDB
- 다낭
- 비지니스 영어
- Business English
- 여행
- JBOSS
- 비교구문
- 조동사
- redis
- 해외여행
- Python Django
- ubuntu
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |