본문 바로가기

프로그래밍/JAVA & SPRING

[LifeSoft] spring 30강 Spring Security

반응형

18. 스프링 시큐리티

가. 스프링 시큐리티의 개요

1) 웹 보안의 3요소

 

가) 인증(Authentication) : 애플리케이션의 작업을 수행할 수 있는 주체(사용자). 현재 접속중인 사용자가 누구인지 확인하는 과정

나) 권한 인가(Authorization) : 인증된 주체가 애플리케이션의 동작을 수행 할 수 있도록 허락되어있는지 증명하는 과정. 현재 사용자가 특정 url에 접속할 권한이 있는지 검사하는 과정

다) UI 처리 : 권한이 없는 사용자가 접근할 경우의 에러 화면 등을 보여주는 과정.

 

2) 스프링 시큐리티

개발자가 직접 처리하던 보안 처리과정을 스프링 프레임워크에서 제공하는 스프링 시큐리티를 사용하여 사용권한 관리, 비밀번호 암호화, 회원가입 처리, 로그인, 로그아웃 등의 웹 보안 관련 기능 개발을 쉽게 처리할 수 있음.

 

나. 실습소스

1) 회원정보 테이블 생성

create table users (
  userid varchar2(255) not null,  -- 아이디
  passwd varchar2(255) not null,  -- 비밀번호(암호화 처리)
  name varchar2(255) not null, -- 이름
  enabled number(1) default 1,  -- 사용가능여부
  authority varchar2(20) default 'ROLE_USER',  -- 일반사용자/관리자
  primary key(userid)
);

 

프로젝트를 새로 만든다.

spring legacy project

project name을 spring06_security

Templates은 Spring MVC Project

package는 com.example.security

 

2) pom.xml

여기서는 추가되는 패키지들이 들어간다.

 

<properties>
  <java-version>1.8</java-version>
  <org.springframework-version>5.1.4.RELEASE</org.springframework-version>
  <org.aspectj-version>1.9.2</org.aspectj-version>
  <org.slf4j-version>1.7.25</org.slf4j-version>
  <spring.security.version>5.1.3.RELEASE</spring.security.version>
 </properties>

 

<!-- 오라클 라이브러리 다운로드를 위한 저장소 추가 -->
 <repositories>
  <repository>
   <id>codelds</id>
   <url>https://code.lds.org/nexus/content/groups/main-repo</url>
  </repository>
 </repositories>

 

시큐리티 관련 모듈 추가

  <!-- Spring Security -->
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-core</artifactId>
   <version>${spring.security.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>${spring.security.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>${spring.security.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-taglibs</artifactId>
   <version>${spring.security.version}</version>
  </dependency> 

나머지는 sample 프로젝트랑 동일하게 구성한다.

 

3) WEB-INF/web.xml

설정이 좀 어렵다. 코드도 복잡하다.

 <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>

 

서블릿의 환경 설정 파일에서

서블릿은 기본서블릿(appServlet)으로 똑같다.

기본(default)서블릿을 스프링에서 제공하는 DispatcherServlet을 돌려서

DispatcherServlet이 servlet-context.xml을 읽어서 매핑 처리를 한다. (똑같음)

 

새로들어가는 태그 <listener>

<!-- HttpSessionEventPublisher: 스프링 시큐리티에서 사용하는 세션 이벤트 처리 관련 리스너이다. 세션만료 체크, 동시 로그인 제한 등의 기능 제공 -->
 <listener>
  <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
 </listener>  

 

애플리케이션에서 요청이 들어왔을때 일단 스프링 시큐리티에서 보안체크를 한 다음에

로그인 여부를 검사한다든지 그런 것들을 한다는 것이다.

 <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>

 

 <!-- 한글 처리를 위한 인코딩 필터 삽입 -->

 

 <!-- 에러 처리 페이지 -->
 <error-page>
  <error-code>500</error-code>
  <location>/user/login</location>
 </error-page>
 
 <!-- 세션 타임아웃 설정 (분) -->
 <session-config>
  <session-timeout>20</session-timeout> 
 </session-config>

 

3) WEB-INF/spring/appServlet/servlet-context.xml

 

 

 

 

11) com.example.security.model.dto.UserDTO.java

/*User:사용자의 상세정보를 담는 클래스*/

 

public class UserDTO extends User{
  private String userid;
  public UserDTO(String username, String password, 
    boolean enabled, 
    boolean accountNonExpired,
    boolean credentialsNonExpired, 
    boolean accountNonLocked,
    Collection<? extends GrantedAuthority> authorities,
    String userid) {
      super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
   
     this.userid = userid;
   }
// getter(), setter()
}

 

 

12) com.example.security.model.dao.UserDAO .java

 

public interface UserDAO {
 // 회원 가입 처리
 public int insertUser(Map<String, String> map);
 // 회원 상세정보
 public Map<String, Object> selectUser(String userid);
}

 

 

13) com.example.security.model.dao.UserDAOImpl.java

 

@Repository
public class UserDAOImpl implements UserDAO {
  
 @Inject SqlSession sqlSession;
  
 @Override  // 회원정보 레코드 저장
 public int insertUser(Map<String, String> map) {
  return sqlSession.insert("user.insertUser", map);
 }
 @Override  // 로그인 확인
 public Map<String, Object> selectUser(String userid) {
  return sqlSession.selectOne("user.selectUser", userid);
 }
}

 

 

14) userMapper.xml

 

<mapper namespace="user">
 <insert id="insertUser">
  insert into users
  values
  (#{userid}, #{passwd}, #{name}, 1, #{authority})
 </insert>
 <select id="selectUser" resultType="java.util.Map">
  select 
   userid as username,    // spring security에서 체크하는 필드명으로 맞춘것
   passwd as password, // 내부적으로 암화화됨, 필드명 맞춤
   name,
   enabled,
   authority
  from users
  where userid=#{userid} 
 </select>
</mapper>

 

 

15) com.example.security.service.UserAuthenticationService.java

 

// 우리가 만든 회원테이블(users)을 가지고 spring security에서 인증정보를 관리를 함.
// UserDetailsService: 사용자의 상세정보를 제공하는 서비스임.
// 그 서비스를 implements한다.
public class UserAuthenticationService implements UserDetailsService {
 @Inject SqlSessionTemplate sqlSession;
 @Inject BCryptPasswordEncoder passwordEncoder;
  
 public UserAuthenticationService() {}
 public UserAuthenticationService(SqlSessionTemplate sqlSession) {
  this.sqlSession = sqlSession;
 }
 // 로그인 인증을 처리하는 코드
 // 파라미터로 입력된 아이디값에 해당하는 테이블의 레코드를 읽어옴
 // 정보가 없으면 예외를 발생시킴
 // 정보가 있으면 해당 정보가 map(dto)로 리턴됨
 @Override // 사용자id(username)만 보내면 스프링에서 내부적으로 체크해서 결과를 돌려줌
 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    
  return null;
 }
}

 

 

loadUserByUsername(String username) 메소드만 따로 보면 ... 

 


web.xml Listener, Filter의 활용
http://wiki.gurubee.net/pages/viewpage.action?pageId=26740229
Listener 와 Filter
https://sseambong.tistory.com/83

 


 

Spring 프로젝트 명 바꾸기 (완벽하게 변경하기)
https://codedragon.tistory.com/6226