Web/Servlet && Spring
[Spring] 스프링 시큐리티 (spring security)
jinsiri
2019. 9. 24. 16:53
대부분의 사용자 권한은 세션에 아이디 값을 저장하는 것으로 처리한다.
하지만 스프링 시큐리티를 이용하면 다음과 같은 작업들을 간편하게 처리할 수 있다.
- 로그인, 토큰 처리
- 암호화 처리
- 자동로그인
- JSP에서의 로그인 처리
스프링 시큐리티의 기본동작 방식은 필터와 인터셉터로 처리된다.
filter - 서블릿 자원
Interceptor - 스프링의 빈으로 관리되면서 스프링의 컨텍스트 내에 속한다.
사용방법
1. pom.xml 추가
<!-- 시큐리티 관련객체 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
2. security-context.xml 생성
spring- security를 설정할 때에는 5.0 에러가 발생하는 버그가 있으니 아래와 같이 버젼을 지운다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
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">
<!-- security-context.xml -->
<security:http>
<security:intercept-url pattern="/sample/all"
access="permitAll" />
<security:intercept-url
pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
<security:intercept-url pattern="/sample/admin"
access="hasRole('ROLE_ADMIN')" />
<security:form-login />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="member" password="{noop}member"
authorities="ROLE_MEMBER" />
<security:user name="admin" password="{noop}admin"
authorities="ROLE_MEMBER, ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
3. web.xml 추가
<!-- 스프링 시큐리티 필터 -->
<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>
<-- ****************************************************************************** -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- 공백을 구분자로 한다. -->
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml <--이부분을 추가
</param-value>
</context-param>
4. servlet-context 설정 추기
<!-- 인터셉터 설정 -->
<beans:bean class="com.encore.interceptor.AuthInterceptor"
id="authInterceptor"></beans:bean>
<beans:bean class="com.encore.interceptor.LoginInterceptor"
id="loginInterceptor"></beans:bean>
<interceptors>
<interceptor>
<!-- interceptor가 가로채서 처리해 주세요. -->
<mapping path="/sample/update" />
<mapping path="/sample/delete" />
<beans:ref bean="authInterceptor" />
</interceptor>
<interceptor>
<mapping path="/sample/login" />
<beans:ref bean="loginInterceptor" />
</interceptor>
</interceptors>
5. Sample2Controller.java
package com.encore.controller;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.log4j.Log4j;
@Controller
@RequestMapping("/sample/*")
@Log4j
public class Sample2Controller {
@GetMapping("/all")
public void doAll() {
System.out.println("모든 사용자가 접속할 수 있음");
}
@GetMapping("/member")
public void doMember() {
System.out.println("로그인된 사용자 접속할 수 있음");
}
@GetMapping("/admin")
public void doAdmin() {
System.out.println("관리자 접속할 수 있음");
}
@RequestMapping("/list")
public void list() {
System.out.println(">>>list");
}
@RequestMapping("/delete")
public void delete() {
System.out.println(">>>delete");
}
@RequestMapping("/update")
public void update() {
System.out.println(">>>update");
}
// ------------로그인
@GetMapping("/login")
public void loginForm() {
}
@PostMapping("/loginPost")
public void loginPost(String username, String password, HttpSession session) {
if (username.equals("siri") && password.equals("1234")) {
session.setAttribute("login", "success");
}
}
}
6. AuthInterceptor.java
package com.encore.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class AuthInterceptor extends HandlerInterceptorAdapter {
private void saveDest(HttpServletRequest req) {
String uri = req.getRequestURI();
String query = req.getQueryString();
System.out.println("uri>>>" + uri + ", query>>>" + query);
// 192.168.0.96/sample/delete?id=1234
if (query == null)
query = "";
else
query = "?" + query;
req.getSession().setAttribute("dest", uri + query);
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("========< 전처리 >==========");
// 로그인 사용자 인증!! (만약, 로그인 하였다면 login키:success데이터)
HttpSession session = request.getSession();
Object login = session.getAttribute("login");
if (login == null || !login.equals("success")) {
saveDest(request);// 진행하려고 했던 URL을 세션에 저장!!
response.sendRedirect("/sample/login");
return false;
}
return true;
// return true; -----> 매핑URL실행O (계속진행)
// return false; -----> 매핑URL실행X (실행정지)
}// 1.실행
// 2.실행 ==> 매핑 URL (수정,삭제)
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("========< 후처리 >==========");
}// 3.실행
}
7. LoginInterceptor.java
package com.encore.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
HttpSession session = request.getSession();
String login = (String) session.getAttribute("login");
Object dest = session.getAttribute("dest");
response.sendRedirect(dest != null ? (String) dest : "/board/list");
}
}
반응형