본문 바로가기
프로그래밍/스프링프레임워크

스프링프레임웍 - Spring Security(3) : 사용자/권한 정보 DB사용하기

by pentode 2018. 4. 9.

앞서 "스프링프레임웍 - Spring Security(2) : 커스텀 로그인 화면 및 권한에 따른 접근 제어"에서 로그인 화면을 원하는 형태로 만드는 방법에 대해서 알아 보았습니다.

 

지금까지의 기본설정과 화면 커스터마이징에서는 사용자 정보와 권한 정보가 모두 security-context.xml 파일 안에 있었습니다. 이번에는 이 정보들을 DB 저장하고 이용할 수 있도록 해 보겠습니다. 데이터베이스는 Oracle을 사용합니다.

 

먼저 사용자 정보와 권한정보를 저장할 테이블 구조 입니다. 이 테이블들은 스프링 시큐리티의 DB 지원 기본 구조를 키구조만 조금 바꾼것 입니다.

 

스프링시큐리티 테이블 구조

 

 

1. 사용자/권한 테이블

 

사용자 권한 처리를 위해서 총 5개의 테이블로 구성됩니다. 테이블을 생성하고 기본 데이터를 입력하는 쿼리파일은 글 하단 전체소스내의 doc폴더에 sample.sql 파일에 있습니다. 각각의 테이블에 대해 알아 보도록 하겠습니다.

 

i. users - 회원 정보 테이블

 

- username이 아이디입니다. 여기에서는 비밀번호가 암호화 되지 않았습니다.

- enabled는 boolean 값으로 계정 사용여부를 나타냅니다.

 

ii. authorities - 회원, 권한 관계 테이블

 

- 회원(username)이 가지는 권한정보가 있는 테이블 입니다.

- authority"ROLE_USER", "ROLE_ADMIN" 이 될 것입니다.

 

iii. gropus - 그룹 테이블 입니다.

 

- 그룹에 권한을 할당하고, 사용자에게 그룹을 할당하는 방식으로 권한을 부여할 수 있습니다.

 

iv. group_authorities - 그룹이 가지는 권한 정보 테이블

 

- groupu_idgroups테이블의 id와 관계되는 외래키 입니다.

- authority"ROLE_USER", "ROLE_ADMIN" 이 될 것입니다.

 

v. group_member - 그룹과 회원의 관계 테이블

 

- group_id groups 테이블의 id 입니다.

- username 은 회원 아이디 입니다.

 

 

2. 권한 부여방식

 

위의 테이블들을 가지고 회원에게 권한을 부여하는 방법은 두 가지가 있습니다.

 

첫 번째는 usersauthorities 테이블을 사용하여 권한을 부여 하는 것입니다. users테이블의 정보로 로그인하고, authorities 의 권한정보를 접근 제어를 합니다.

 

두 번째 방법은 users(group_members, groups, group_authorities) 로 처리하는 방법입니다. 역시 users 정보로 로그인하고, 권한은 회원이 속한 그룹에 할당된 권한으로  접근제어를 하는 것입니다.

 

스프링 시큐리티는 먼저 authorities 테이블에서 권한을 확인하고, 다음에 group_members 테이블에서 권한을 확인합니다. 그러므로 두 가지 방법중 하나만 사용하면 됩니다. 즉,  authorities 테이블에 정보가 없어도 group_members 테이블에 정보가 있으면 권한이 부여됩니다. 그 반대로 마찬가지 입니다.

 

 

3. security-context.xml 설정파일을 보겠습니다.

 

회원 정보와 권한 정보를 데이터베이스에서 가져오도록 설정하는 부분입니다.

 

<!--
<beans:bean id="userDetailsService"
            class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
	<beans:property name="dataSource" ref="dataSource"/>
</beans:bean>
-->

<!--  provider  -->
<authentication-manager>
    <authentication-provider>
        <jdbc-user-service
            data-source-ref="dataSource"
            role-prefix=""
            users-by-username-query="select username, password, enabled from users where username = ?"
            authorities-by-username-query="select username, authority from authorities where username = ?"
            group-authorities-by-username-query="select g.id, g.group_name, ga.authority from groups g, group_members gm, group_authorities ga where gm.username = ? and g.id = ga.group_id and g.id = gm.group_id"
        />
    </authentication-provider>
</authentication-manager>

 

인증 정보를 가져오는 기능을 하는 인터페이스가 org.springframework.security.core.userdetails.UserDetailsService 입니다. 데이터베이스에서 정보를 가져오도록 이 인터페이스를 구현해둔 클래스가 org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl 입니다. 위 코드의 id"userDetailsService"인 빈이 이것 입니다. 이 빈에 대한 정의는 넣지 않아도 됩니다.

 

이 빈은 <jdbc-user-service> 요소로 사용되어 집니다. 각 속성들을 알아보겠습니다.

 

- data-source-ref="dataSource" : 데이터베이스 연결을 나타내는 dataSource 입니다. root-contxt.xml 파일에 정의 되어 있습니다.

- role-prefix : "ROLE_" 와 같은 롤 앞에 붙는 prefix 를 지정합니다. 권한 체크시 여기에 지정된 값을 붙여서 확인합니다. 데이터베이스에 ROLE_USER 형식으로 데이터를 넣어 둿으므로 여기서는 값을 주지 않았습니다.

- users-by-sername-query="" : 아이디로 사용자 정보를 가져오는 쿼리 입니다. users 테이블에서 정보를 가져옵니다.

- authorities-by-username-query="" : authorities 테이블로부터 권한정보를 가져옵니다.

- group-authorities-by-username-query="" : 그룹/회원 관계로부터 권한정보를 가져옵니다.

 

 

이것으로 해서 회원/권한 정보를 데이터베이스로부터 가져오는 처리를 해보았습니다. 하지만 아직 한가지가 처리되지 않을 것이 있습니 다. URL별로 권한을 지정하는 부분이 아직도 xml 파일에 남아 있습니다. 다음 코드 입니다.

 

<intercept-url pattern="/login/loginForm.do" access="permitAll" />
<intercept-url pattern="/home.do" access="permitAll" />
<intercept-url pattern="/admin/**" access="hasRole('ADMIN')" />
<intercept-url pattern="/**" access="hasAnyRole('USER, ADMIN')" />

 

다음글에서는 이 정보도 데이터베이스로 부터 가져오도록 하는 방법에 대해서 알아보도록 하겠습니다.

 

 

4. 실행결과

- 최초 실행화면으로 홈 화면 입니다. 로그인 되어있지 않으므로 로그인 링크가 있습니다.

 

홈화면

 

- 로그인 화면입니다. 일반계정인 user/1 로 로그인 합니다.

 

로그인 화면

 

- 로그인후 홈화면으로 이동합니다. 로그인 되어 있으므로 로그아웃 버튼이 있습니다.

 

로그인된 홈 화면

 

- 소개페이지 링크를 눌러 들어가 보았습니다. 로그인되어 있으므로 페이지가 보입니다. 로그인 되어 있지 않다면 로그인 페이지로 갈 것입니다.

 

일반 사용자 권한 소개 페이지

 

- 일반계정으로 로그인 한 상태에서 관리자 홈 링크를 클릭하면 Access Denied 메세지가 보입니다.

 

일반 권한으로 관리자 페이지 접근

 

- 관리자 아이디 (admin/1) 로 로그인 후 관리자 홈 링크를 클릭하면 관리자페이지로 들어가 입니다.

 

관리자 페이지

 

 

※ 전체소스

spring_security(3).zip
다운로드

 

반응형