웹 어플리케이션을 개발할 때 프로그래머를 괴롭게 만드는 것중 하나가 바로 보안 입니다. 허가된 사용자만 접근할 수 있도록 접근권한을 제어하고, 중요한 정보는 HTTPS같은 프로토콜을 이용하여 암호화하여 주고받기도하며, 사용자의 로그인 암호나 신용카드 번호같은 민감한 정보들은 DBMS에 암호화하여 저장해야합니다. 이렇게 글로만 봐도 정말 막막한 느낌이 드는건 저뿐인가요..? 보안관련해서 웹어플리케이션 개발자의 코딩과 직결된 3가지는 다음과 같습니다.
- 인증(Authentication)처리 : 현재 사용자가 누구인지 확인하는 과정으로, 일반적으로 아이디/암호를 이용해 처리
- 인가(Authorization)처리 : 현재 사용자가 특정 대상(URL, 기능)을 사용(접근)할 권한이 있는지 검사
- UI처리 : 권한이 없는 사용자가 접근했을 때, 알맞은 에러화면을 보여주거나 로그인 폼 등 인증화면으로 이동
보통 웹어플리케이션에서는 로그인을 통해 인증을 처리하고, 인증된 정보를 쿠키나 세션에 저장시킵니다. 그리고 저장된 인증정보를 이용해서 동일사용자에게서 요청이 왔을 때 사용자가 누군지 식별합니다. 보통 URL을 통해서 사용자 접근권한을 제한하는데, 예를들어 사용자1이 관리자 권한을 가진다고 했을 때, /admin/board/boardList 라는 URL에 접근하면인증과 인가모두 통과되어 게시판목록을 확인할 수 있습니다. 하지만 사용자2(일반회원)가 /admin/member/memberList 라는 URL로 접근하면 사용자2라는 회원인증은 되었지만, admin(관리자)에 접근할 수 있는 권한은 없기 때문에 인가가되지 않습니다. 따라서 알맞은 에러메시지를 출력해서 보여주게 됩니다.
위에서 설명한 인증-인가-UI처리는 웹 어플리케이션마다 모두 유사한 구조를 가지고 있습니다. 따라서 매번 새롭게 구현하기 보다는 기본 틀을 만들고 어플리케이션마다 다른 부분만을 알맞게 구현함으로써 설계, 코드작성에 드는 시간을 단축시킬 수 있습니다. 스프링 시큐리티(Security) 프로젝트는 정확히 이러한 목적으로 만들어졌습니다.
따라서 개발자들은 처음부터 인증, 인가, ui처리를 위한 코드를 작성하기보다는 스프링 시큐리티가 제공하는 틀을 사용하고 필요한 부분만 커스터마이징하는 식으로 사용하면 빠르게 인증, 인가부분을 마무리 할 수 있습니다.
간단한 스프링 시큐리티 예제를 작성해 보겠습니다.
1. Maven 의존설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<dependencies>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
</dependencies>
|
cs |
2. 스프링 시큐리티 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
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
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">
<sec:http use-expressions="true">
<sec:intercept-url pattern="/admin/**" access="hasAuthority('ROLE_ADMIN')"/>
<sec:intercept-url pattern="/manager/**" access="hasRole('ROLE_MANAGER')"/>
<sec:intercept-url pattern="/member/**" access="isAuthenticated()"/>
<sec:intercept-url pattern="/**" access="permitAll"/>
<sec:form-login/>
<sec:logout/>
</sec:http>
<sec:authentication-manager>
<sec:authentication-provider>
<sec:user-service>
<sec:user name="bkchoi" password = "1234" authorities="ROLE_USER"/>
<sec:user name="manager" password = "qwer" authorities="ROLE_MANAGER, ROLE_USER"/>
<sec:user name="admin" password = "admin" authorities="ROLE_ADMIN, ROLE_USER"/>
</sec:user-service>
</sec:authentication-provider>
</sec:authentication-manager>
</beans>
|
cs |
10번째 라인의 <sec:http>태그가 핵심입니다. 속성중 use-expressions="true"는 access부분에 스프링이 제공하는 SpEL(스프링 표현식)을 사용할 수 있도록 만들어줍니다. 표현식을 사용하면 접근 IP제한과 같이 좀 더 풍부한 접근 제한을 설정할 수 있습니다. intercept-url 태그내의 hasAuthority와 hasRole은 같은 속성인데 ()안에있는 권한을 가진 사용자만이 접근할 수 있게 해주는 속성입니다. 그리고 permitAll은 누구나 접근 가능하다는 속성입니다.
15라인의 <login-form/>태그는 인증된 사용자만 허용되는 경로에 접근할 때, 로그인 폼을 보여주고, 로그인 폼에서 아이디/암호를 전송하면, 로그인(인증)처리를 합니다.
19-27라인은 테스트목적으로 스프링 시큐리티가 제공하는 인메모리 사용자 DB기능을 이용해 몇개의 유저를 만든것입니다. authorities 속성은 사용자가 갖는 권한목록을 정의합니다.
'Spring' 카테고리의 다른 글
Spring(17) - 웹 어플리케이션 구조 (0) | 2019.04.23 |
---|---|
Spring(16) - Mybatis연동 (0) | 2019.04.18 |
Spring(15) - JPA, ORM, Hibernate, Mybatis (0) | 2019.04.18 |
Spring(14) - 데이터베이스 연동(JDBC), 트랜잭션 (0) | 2019.04.17 |
Spring(13) - WebSocket (0) | 2019.04.16 |