ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] 스프링 시큐리티 (spring security)
    Web/Servlet && Spring 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");
    	}
    }
    
    반응형

    댓글

Designed by Tistory.