본문 바로가기
Tech/Web

Spring-Web-Security

by 소라소라잉 2019. 11. 15.

* 인터셉터 ( Interceptor )

Interceptor란 컨트롤러에 들어오는 요청(HttpRequest)과 컨트롤러가 응답하는 HttpResponse를 가로채는 역할을 함. 

 

* Web페이지(WebApp)를 띄우면 Web Context(경계선/범위..라고생각)가 만들어 짐 => 서블릿에선 Servlet Context라고 부르고, jsp에선 그냥 Application라고 부름 -> 이거에 대한 소개서(?)가 web-inf안의 web.xml

스프링은 web context 안에 application context를 만든다. 

(* Filter와 Interceptor의 차이점 ▽)

필터는 web context에 두기 때문에 application context안에 있는 bean들은 필터의 존재를 모른다.

필터는 외부세계에 존재하는 개념, 인터셉터는 스프링 내부세계에 존재하는 개념. 

인터셉터는 필터와 비슷하지만 인터셉터는 application context에 있는 빈들과 같이 일(?)을 할 수 있다. 

so, 로그인,아웃같은 경우 spring을 쓴다면 필터를 쓸 필요 없고 인터셉터를 이용하면 쉽게 할 수 있다. 

필터는 주로 앞에서 동작, 인터셉터는 앞,뒤로 동작 할 수 있음(경계에 있나보당).

so aop할때 controllrer에는 적용 시키지 않고..블라블라 

 

 

 

------------실습시작------------

 

spring 세팅 -> spring버전, jdk버전, log4j설정 변경 

 

Spring security는 webmvc와는 다르게 외부 모듈이라 별도 라이브러리가 필요함 -> maven spring security (core,web,security config(java configuration잡을때 필요), crypto, taglibs(jsp에서 사용가능-JSP환경-) 라이브러리 버전은 전부 통일되어야 함 => 우린 5.1.7)

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
        <!-- CORE -->
        <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <!-- WEB -->
        <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <!-- CONFIG -->
        <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <!-- TAGLIBS -->
        <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
cs

 

Spring 폴더에 new => Spring Bean Configuration File => 'security-context.xml' => namespace에 security 체크 후 저장 => web.xml 설정변경

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 
    <!-- The definition of the Root Spring Container shared by all Servlets 
        and Filters -->
    <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>
 
    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    e
 
    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
    <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>
 
 
 
</web-app>
 
cs

  

security-context.xml 설정 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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/security
    http://www.springframework.org/schema/security/spring-security.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <security:http>
        <security:form-login />
    </security:http>
 
    <security:authentication-manager>
    </security:authentication-manager>
 
</beans>
cs
1
2
<security:authentication-manager>
</security:authentication-manager>
cs

=> 이부분이 중요함! authentication-manager : 인증하면 인가작업이 이루어짐 

 

SampleController.java 생성 ppt 메서드 3개 작성  & views->sample->jsp3(all/admin/member)개만들기 

security 적용시 get방식 말고 모두 막힘. => 왜?   (post는 인터셉터가 어쩌고 저쩌고 가로챔) 

 

security-context.xml 변경

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
<?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/security
    http://www.springframework.org/schema/security/spring-security.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <security:http>
        <security:form-login />
        <security:intercept-url pattern="/sample/all"
            access="permitAll" />
        <security:intercept-url
            pattern="/sample/member" access="hasRole('ROLE_MEMBER')" />
    </security:http>
 
    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="user00" password="user00"
                    authorities="ROLE_MEMBER" />
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
 
</beans>
cs

 

이러면 sample/all로 들어갔을땐 all페이지가 뜨고, member로 들어갔을땐 로그인 페이지가 뜸!!!

 

단순 로그인을 구현해보자 

* spring security은 사용자를 user라는 이름을 사용하고 사용자를 '구분'할때 ID라는 용어를 사용하지 않고 name을 사용함. so 시큐리티 접목시 user와 name을 사용하지 말고 다른이름 (member..or something) 사용하는게 좋다.

 

위와같이 설정하면 에러뜬다. 

패스워드 인코딩 때문(머라는지 못들었음)

쨌든 pasword 설정을 password="{noop}user00"로 변경해줘야함

 

& admin 도 하나 맨들어주자.

1. member로 로그인했을때 admin페이지에서는 접근금지 떠야하고

2. admin으로 로그인하면 admin,member페이지 둘다 떠야함.

 

member의 로그인이 deny됐을때(member가 admin으로 들어가려고 했을때) 403페이지를 보여주는 것 보다 다른페이지를 보여주는게 좋으니까... 

security:http안에 errorpage추가 후 error페이지 작성 

그러나 이렇게 하면 URL만 지정한 상태이지 저쪽으로 옮겨주는 controller가 없기 때문에 이동은 안함.

정확히 말하면 error-page의 page는 page(jsp)가 아니라 Just URI 임. => controller를 만들자!

 

컨트롤러를 만들었다는 자체가 커스터마이징을 하겠다는 뜻.

따라서 여러가지 파라미터를 받아 처리해줄 수 있는데 

model에 'msg'이름으로 attribute를 설정해서 jsp페이지에 뿌려줄수도 있고 ㅎㅎ

(accessError 페이지 ppt복붙)

 

customLogin 페이지 만들고(ppt복붙) xml설정 변경

로그인페이지를 spring security의 디폴트 페이지 말고 내가 만든 페이지(customLogin)로 할 수 있다. 

 

 

 

* CSRF Token (CSRF공격을 막기 위한 Token) 

Cross-site request forgery, => 나는 a사이트를 보고있다고 생각하지만 b사이트에 접근하고 있음.

b사이트의 접근을 막기 위해서 매번 접근시마다 token값을 달리해줌(이해도 안되고 이 설명이 맞는지도 모르겠으니까 나중에 수정해라) 

 

value값이 들어갈때마다 달라짐! (: 사실은 세션쿠키 라이프사이클에 맞춰서 달라짐) 

=> 모든 post방식은 기본적으로 csrf토큰이 필요함.(get은 조회만 하니께... post는 작업을 해줄수 있잖아) 

 

=> 스프링 시큐리티를 접목하면 모든 post방식은 csrf토큰을 요구한다.

(jsp페이지의 hidden부분을 지우면 405 에러가 남) 

 

 

 

Bcrypt 설정 (password 저장용) 

 

DB (MySQL 연결) 

 

 

 

============================================================

 

DAY 2 

(로그인 했을때 처리하는 것들, & 로그아웃) 

 

SQL수정(설정) 

MyBatis연동 -> 커스텀 userservice라고 함

자동 로그인 

+ (소셜로그인? 공부해야함)

 

-----------------------------------------------------

 

1. org.zerock.security 패키지 생성

- 로그인처리와 관련된 설정 해주기 

- class CustomLoginSuccessHandler implements AuthenticationSuccessHandler

 

-security쪽은 빈 설정 할 때 어노테이션 안쓰고 xml 설정으로 해준다...(왜냐면 헷갈리니까)

=> bean으로 잡아줘라

 

 

.

.

.

.

 

credential - principal 비교! 

credential : ?

principal : 현재 로그인한 사용자에 대한 정보  

 

spring security는 username(ID)만 only 가져올 수 있음 -> so 커스터마이징 필요 (다른 정보들도 가져오고 싶으니깐...(이름..닉네임..등등))

커스터마이징하다 => userdetailsservice(manager..or..) 인터페이스를 구현하다.

※ OOP 공부할거면 userdetails interface상속구조 보세요 

 

 

-----------------------------------

커스터마이징 단계 

1. (db쓸거니까) MyBatis 구조 ,세팅 필요(테이블만들고 연결)  => Test 진행(사용자 로그인..)

2. CustomUserService 제작=> 기본적인 로그인,로그아웃 처리 가능(웹에다가 붙이기)

3. JSP 페이지에 출력 

 

 

 

 

 

 

댓글