스프링 시큐리티 인증 예제 (MyBatis MySql 연동)

 

✅ 시나리오

아래와 같이 총 4개의 페이지가 있다. 먼저 사용자는 웹에 접속하면 login.jsp 페이지를 통해서 로그인 인증을 거쳐야 한다. login.jsp에서 로그인 성공을 하면 top.jsp로 이동된다. 그리고 top.jsp 에서 a 태그를 통해서 user.jsp 또는 admin.jsp 로 이동 할 수 있다. 이 부분은 나중에 인가 관련 기능을 구현하기 위해서 user.jsp, admin.jsp 를 만들었기 때문에 여기서는 중요하지 않다. 여기서 중요한것은 login.jsp와 top.jsp이다. 스프링 시큐리티를 통해서 어떻게 login.jsp를 거쳐서 top.jsp로 갈 수 있는지 살펴보자.

 

-login.jsp 페이지(로그인화면)
-top.jsp 페이지(메인화면)

 

-user.jsp 페이지(유저권한페이지)

-admin.jsp 페이지(관리자권한 페이지)

 

✅ 스프링 프로젝트 생성

프로젝트 구조

먼저 new를 통해서 스프링 레거시 프로젝트를 생성해준다.

 

 

pom.xml 에서 라이브러리 다운로드

pom.xml에서 필요한 라이브러리를 다운로드 해준다. 상단 properties 태그에 스프링 시큐리티 버전을 적어주고, 아래 스프링 시큐리티 라이브러리, jdbc, datasource, jdbcDriver, mysql, mybatis 등 필요한 라이브러리 태그를 작성해준다. 그리고 org.apache.maven.plugins의 source 와 target을 1.8로 맞춰준다. 그러면 자바도 자동으로 1.8버전으로 맞춰진다. 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.spring</groupId>
	<artifactId>my</artifactId>
	<name>Test3</name>
	<packaging>war</packaging>
	<version>1.0.0-BUILD-SNAPSHOT</version>
	<properties>
		<java-version>1.8</java-version>
		<org.springframework-version>4.2.6.RELEASE</org.springframework-version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
		<org.slf4j-version>1.6.6</org.slf4j-version>
		
        <!-- Spring  시큐리티 -->
		<org.springframework.security-version>4.0.4.RELEASE</org.springframework.security-version>
	</properties>
	<dependencies>
		
        ..중간생략

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




	<!-- DB 프로그래밍을 위해 필요한 Library 
		1.jdbc class: spring-jdbc org.springframework.jdbc.core.JdbcTemplate 
		2.data source: commons-dbcp org.apache.commons.dbcp.BasicDataSource 
		3.jdbc driver: mysql-connector-java com.mysql.jdbc.Driver -->

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
	
	
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
	
	
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.12</version>
		</dependency>
		
		
		    <!-- 마이바티스 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.5</version>
		</dependency>
	
		<!-- 마이바티스 스프링 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.3.1</version>
		</dependency>
		   
		   
	</dependencies>
   
   
   .. 하단 생략

 

 

Mabatis와 Mysql 연동 설정(/WEB-INF/spring/sql/sqlSessionFactory.xml)

위의 경로에 sqlSessionFactory.xml 파일을 작성해준다. 이 파일은 DB연동과 관련된 파일이다. 순서대로 보면 먼저 DB Connection pool을 관리할 객체인 DataSource Bean을 설정해준다. 본인의 mysql 정보를 아래와 같이 작성해준다. 그리고 SqlSessionFactory Bean 설정을 해준다. SqlSessionFactory는 3개의 객체를 참조한다.

 

위에서 만든Datasource, mybatis 설정파일 마지막으로 Dao 인터페이스 구현체이면서 쿼리가 작성되어 있는 mapper xml의 경로이다. 그후, SqlSessionTemplate Bean을 정의해주고 인증을 위한 Dao 인터페이스를 구현한 매퍼 Bean을 작성해준다. MapperFactoryBean은 SqlSessionFactory를 참조한다. 마지막으로 jdbc:initialize 태그를 이용해서 인증에 필요한 테이블 생성, 인증관련 데이터를 insert 해준다.  jdbc:initialize에 작성된 sql은 서버가 시작될때 작동되어 테이블을 만들고 데이터를 넣는다. 최초에 한번 실행해주고, 이후에는 주석처리를 해주자.

<?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:context="http://www.springframework.org/schema/context"
  xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
  xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/jdbc
    http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://mybatis.org/schema/mybatis-spring 
    http://mybatis.org/schema/mybatis-spring.xsd    
    ">

	<!-- 
		 Data Source 설정 
		 mysql 8.0 부터는 url 에 ?serverTimezone=UTC 넣어야함. 
		 driverClassName 은 com.mysql.cj.jdbc.Driver 
		서드파티가 제공하는 데이터 소스 - Apache Commons DBCP 
	-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
     <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
     <property name="url" value="jdbc:mysql://localhost:3306/MYDB?serverTimezone=UTC&amp;useSSL=false"/>
     <property name="username" value="root" />
     <property name="password" value="1111@" /> 
    </bean>


	<!-- sqlSessionFactory  -->
	  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	      <property name="dataSource" ref="dataSource" />
	      <property name="configLocation" value="/WEB-INF/spring/sql/mybatis-config.xml"/>
	      <property name="mapperLocations" value="classpath:/META-INF/sql/*.xml" />
	  </bean>
	
	
	<!--  SqlSessionTemplate -->
	 <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" destroy-method="clearCache">
	     <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
	 </bean>
	
	
		<!-- 인증을위한 Dao 인터페이스 구현 매퍼 -->
	  <bean id="authDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
	    <property name="mapperInterface" value="com.spring.my.authentication.SampleUserDetailDAO" />
	    <property name="sqlSessionFactory" ref="sqlSessionFactory" />
	  </bean>



	<!-- 초기화 -->
  	<jdbc:initialize-database data-source="dataSource" ignore-failures = "DROPS">
	    <jdbc:script location="classpath:/META-INF/script/ddl.sql" />
    	<jdbc:script location="classpath:/META-INF/script/dml.sql" />
	</jdbc:initialize-database> 


</beans>

 

 

mybatis-config.xml 작성 (/WEB-INF/spring/sql/mybatis-config.xml)

mybatis 설정과 관련된 정보들이 들어있다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
  </settings>
</configuration>

 

 

auth.xml 작성 (/META-INF/sql/auth.xml )

나중에 아래에서 독자적으로 인증을 구현할때 사용될 매퍼이다. 로그인할 때 입력한 id를 이용해서 해당 사용자가 존재하는지, 해당 권한이 존재하는지 조회하는 쿼리다. SampleUserDetailDAO는 나중에 독자적인 인증을 구현하는 부분에서 작성된다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.spring.my.authentication.SampleUserDetailDAO">

 
     <select id="checkUser" parameterType="string" resultType="com.spring.my.authentication.MyUser">
         select LOGIN_ID, PASSWORD, FULL_NAME, DEPT_NAME
              from T_USER
              where LOGIN_ID = #{username}
    </select>
 
  
 
      <select id="checkAuth" parameterType="string" resultType="com.spring.my.authentication.MyUser">
         		select LOGIN_ID, ROLE_NAME
	              from T_ROLE
	                inner join T_USER_ROLE on T_ROLE.ID = T_USER_ROLE.ROLE_ID
	                inner join T_USER on T_USER_ROLE.USER_ID = T_USER.ID
	              where LOGIN_ID = #{username}
     </select>
 
</mapper>

 

 

✅ ddl.sql 작성  (/META-INF/script/ddl.sql)

사용자 인증 정보 관련 테이블 생성 쿼리

drop table if exists T_USER_ROLE ;
drop table if exists T_USER;
drop table if exists T_ROLE;

create table T_ROLE
(
  ID BIGINT primary key,
  ROLE_NAME varchar(100) not null,
  DESCRIPTION varchar(100) not null
)
;

create table T_USER
(
  ID BIGINT primary key,
  LOGIN_ID VARCHAR(20) not null,
  PASSWORD VARCHAR(200) not null,
  FULL_NAME VARCHAR(100) not null,
  DEPT_NAME VARCHAR(100)
)
;

create table T_USER_ROLE
(
  USER_ID BIGINT,
  ROLE_ID BIGINT,
  primary key(USER_ID, ROLE_ID)
)
;

 

 

✅ dml.sql 작성 (/META-INF/script/dml.sql)

사용자 인증 정보 관련 데이터 삽입

delete from T_USER_ROLE;
delete from T_ROLE;
delete from T_USER;

insert into T_ROLE values(1, 'ROLE_USER', '일반 롤');
insert into T_ROLE values(2, 'ROLE_ADMIN', '관리 롤');

insert into T_USER values(1, 'user', '1111', '사용자1', '개발부');
insert into T_USER values(2, 'admin', '1111', '사용자2', '관리부');

insert into T_USER_ROLE values(1, 1);
insert into T_USER_ROLE values(2, 2);

 

 

스프링 시큐리티 설정파일 작성 (/WEB-INF/spring/beans-security-db.xml)

아래 설정파일에서 1번은 스프링 시큐리티 필터에서 접근 가능한 url을 설정해준다. 누구든지 인증전에 로그인 페이지를 거쳐야 되기 때문에 /login.jsp 가 포함된 url은 접근가능하게 permitAll 메소드를 적용시켰다. 그리고 2번은 인가 관련된 부분이라 여기서는 작성하지 않고 주석처리 해뒀다. 3번도 마찬가지로 접근를 제어하는 태그이다. isAuthenticated() 메소드로 인증이 완료된 사람들만 해당 url로 접근이 가능하도록 처리 했다. 

 

4번은 로그인 방식을 폼로그인 방식을 채용했다. login.jsp 페이지 안에 form으로 로그인 할 수 있는 html 태그들이 작성되어 있고 로그인 버튼을 누르면 /processLogin url이 호출된다. 그리고 성공하면 top.sjp 페이지로 이동하고 실패하면 login.jsp로 다시 되돌아간다. 로그인 할때 전달되는 id와 패스워드의 파라미터 name도 paramLoginId, paramPassword로 입력해 준다. 

 

그리고 그 후 부터가 중요하다. 여기서는 스프링 시큐리티 클래스인 SampleJdbcDaoImpl 클래스를 통한 인증, 본인이 만든 서비스 클래스 SampleUserDetailsService 클래스를 통한 인증 두가지를 살펴 볼것이다.

 

 

🔅 스프링 시큐리티 인증

먼저 스프링 시큐리티 클래스인 SampleJdbcDaoImpl 클래스 설정하는 부분을 보면 beans:bean 태그를 이용해서 아래와 같이 설정을 한다. usersByUsernameQuery 에는 login id를 통해서 사용자를 찾는 쿼리를 작성해주고, authoritiesByUsernameQuery에는 login id를 통해서 권한을 찾는 쿼리를 작성해준다. bean id는 userServiceDao 로 설정한다. 그리고 아래 authentication-manager 의 authentication-provider 가 Bean id로 참조 할 수 있게 작성한다.

<authentication-provider user-service-ref="userServiceDao">

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <http>
  
  
  <!-- 1.로그인 하지 않는 사용자도 엑세스 가능 -->
  <intercept-url pattern="/login.jsp" access="permitAll()"/>

  
  <!-- 2.admin이하는 ROLE_ADMIN에 설정된 사용자로 로그인한 경우에만 엑세스 가능 -->
<!--    <intercept-url pattern="/admin/**" access="hasAuthority('ROLE_ADMIN')"/> 
  		<intercept-url pattern="/user/**" access="hasAuthority('ROLE_USER')"/>  
  -->
  
  
  <!-- 3.상기 이외의 경로는 인증된 사용자만 엑세스 가능 -->
   <intercept-url pattern="/main" access="isAuthenticated()"/>
  <intercept-url pattern="/**" access="isAuthenticated()"/>
  
  
  
  <!-- 4.로그인 방식에는 폼로그인 방식 채용 -->
  <form-login 
  	login-page="/login.jsp" 
  	login-processing-url="/processLogin" 
  	
  	default-target-url="/top.jsp" 
  	
  	authentication-failure-url="/login.jsp" 
  	username-parameter="paramLoginId" 
  	password-parameter="paramPassword"
  	/>
 
 
  <logout logout-url="/logout" logout-success-url="/login.jsp" invalidate-session="true"/>
  
  <csrf disabled="true" /> 
  
  </http>


<!-- SampleJdbcDaoImpl 의 Bean 설정 파일 -->
<!-- 스프링 프레임워크가 인증 --> 
<beans:bean id="userServiceDao" class="com.spring.my.authentication.SampleJdbcDaoImpl">

	<beans:property name="dataSource" ref="dataSource" />
	<beans:property name="usersByUsernameQuery">
		<beans:value>
			  select LOGIN_ID, PASSWORD, FULL_NAME, DEPT_NAME
              from T_USER
              where LOGIN_ID = ?
		</beans:value>
	</beans:property>


	<beans:property name="authoritiesByUsernameQuery">
		<beans:value>
				  select LOGIN_ID, ROLE_NAME
	              from T_ROLE
	                inner join T_USER_ROLE on T_ROLE.ID = T_USER_ROLE.ROLE_ID
	                inner join T_USER on T_USER_ROLE.USER_ID = T_USER.ID
	              where LOGIN_ID = ?
		</beans:value>
	</beans:property>
</beans:bean>
	



<!-- SampleUserDetailsService 의 Bean 설정 파일 -->
<!-- 사용자가 독자적으로 인증할 클래스파일 생성했을때 -->
<!-- SampleUserDetailsService 객체가 생성될 때, 매퍼 authDao 를 생성자를 통해서 주입해준다. -->
<beans:bean id="userService" class="com.spring.my.authentication.SampleUserDetailsService">
	<beans:constructor-arg ref="authDao"></beans:constructor-arg>
</beans:bean>

  
  <!-- 5. authentication-manager에 등록 -->
	<authentication-manager>
		<authentication-provider user-service-ref="userService">
			<!-- <password-encoder hash="bcrypt"/> -->
		</authentication-provider>
	</authentication-manager>

</beans:beans>

 

 

스프링 시큐리티 인증에 필요한 데이터 전송을 위한 VO

package com.spring.my.authentication;

import java.util.Collection;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;


//UserDetails 오브젝트의 확장
public class SampleUser extends User {



	private String fullName;

    private String deptName;

    
    
	//생성자
    public SampleUser(String username, 
    			      String password,
    			      Collection<? extends GrantedAuthority> authorities
    			      ) 
    {
        super(username, password, authorities);
        
    }

    
  //세터 게터 생략...

    private static final long serialVersionUID = 5869301720811314860L;
}

 

 

JdbcDaoImpl을 확장한 SampleJdbcDaoImpl 작성

실제로 스프링 시큐리티의 인정 처리가 일어나는 부분이다. 앱이 구동되고, 사용자가 로그인 할때 실행된다.

package com.spring.my.authentication;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;

//JdbcDaoImpl 클래스를 상속한 클래스 작성.
//데이터베이스에서 필요한 정보 취득해서 그 정보로, SampleUser 오브젝트 생성
public class SampleJdbcDaoImpl extends JdbcDaoImpl {
 
	
	//데이터 베이스에서 앱의 고유 정보를 취득할 수 있게 loadUsersByUsername 메소드 오버라이드
	//JdbcDaoImpl 에 존재하는 loadUsersByUsername 메소드 참조해도 좋음
	//인자로 인증정보 취득할 sql 지정
	//SELECT 구문에 FULL_NAME과 DEPT_NAME을 지정해 두면 3번과 같이 사용가능
    @Override
    protected List<UserDetails> loadUsersByUsername(String username) {
    	
    	System.out.println("SampleJdbcDaoImpl 클래스 - loadUserByUsername 진입");
    	
        return getJdbcTemplate().query(getUsersByUsernameQuery(), new String[] { username },
                new RowMapper<UserDetails>() {
                        public UserDetails mapRow(ResultSet rs, int rowNum)
                                        throws SQLException {
                                String loginId = rs.getString("LOGIN_ID");
                                String password = rs.getString("PASSWORD");
                                
                                //3
                                String fullName = rs.getString("FULL_NAME");
                                String deptName = rs.getString("DEPT_NAME");
 
                                SampleUser user = new SampleUser(loginId, password,
                                                AuthorityUtils.NO_AUTHORITIES);

                                //4 위에서 조회한 내용을 돌려준다.
                                user.setFullName(fullName);
                                user.setDeptName(deptName);

                                return user;
                        }
                });
    }

    @Override
    protected UserDetails createUserDetails(
            String username, UserDetails userFromUserQuery,
            List<GrantedAuthority> combinedAuthorities) {
    	
    	System.out.println("SampleJdbcDaoImpl 클래스 - createUserDetails 진입");
    	
        SampleUser origin = (SampleUser) userFromUserQuery;
        String loginId = origin.getUsername();
        String password = origin.getPassword();
        String fullName = origin.getFullName();
        String deptName = origin.getDeptName();

        SampleUser user = new SampleUser(loginId, password, combinedAuthorities);
        user.setFullName(fullName);
        user.setDeptName(deptName);

        return user;
    }
}

 

 

🔅 독자적인 인증처리

위에서 스프링 시큐리티 프레임워크의 JdbcDaoImpl을 이용해서 인증처리를 했다면 이번에는 독자적인 서비스 클래스를 만들어서 인증처리를 해주겠다. 다시 /WEB-INF/spring/beans-security-db.xml 이 파일로 돌아가서, 아래 코드를 확인해보자. 아래 코드는 직접 인증을 처리하기 위해서 스프링의 UserDetailService를 구현한 클래스를 통해서 인증을 처리하는 코드이다. 

<!-- SampleUserDetailsService 의 Bean 설정 파일 -->
<!-- 사용자가 독자적으로 인증할 클래스파일 생성했을때 -->
<!-- SampleUserDetailsService 객체가 생성될 때, 매퍼 authDao 를 생성자를 통해서 주입해준다. -->
<beans:bean id="userService" class="com.spring.my.authentication.SampleUserDetailsService">
	<beans:constructor-arg ref="authDao"></beans:constructor-arg>
</beans:bean>

  
  <!-- 5. authentication-manager에 등록 -->
	<authentication-manager>
		<authentication-provider user-service-ref="userService">
			<!-- <password-encoder hash="bcrypt"/> -->
		</authentication-provider>
	</authentication-manager>

 

VO 작성

package com.spring.my.authentication;

public class MyUser{

	private String loginId;
	
	private String password;

	private String fullName;

    private String deptName;

   //셋터 겟터 생략..

    

}

 

DAO 작성

package com.spring.my.authentication;

public interface SampleUserDetailDAO {

    
	public MyUser  checkUser(String username) throws Exception;
    
    public MyUser  checkAuth(String username) throws Exception;
    
    
}

 

Service 작성

Dao를 통해 DB에 접근해서 사용자 정보가 있는지 확인후 마지막에 loadUserByUsername 메소드 리턴값으로 new User(username , password, authorities) 정보를 던져주면 커스텀하게 구현된 인증은 마무리 된다.

package com.spring.my.authentication;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;


public class SampleUserDetailsService implements UserDetailsService{

	
    
    @Autowired
    private SampleUserDetailDAO sampleUserDetailDAO;
	
    

	public SampleUserDetailsService(SampleUserDetailDAO sampleUserDetailDAO) {
		
		super();
		
		this.sampleUserDetailDAO = sampleUserDetailDAO;
		System.out.println("SampleUserDetailsService 초기화 됨");
		System.out.println("sampleUserDetailDAO :" + sampleUserDetailDAO);
		
	}



	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		
		System.out.println("SampleUserDetailsService 클래스 - loadUserByUsername 진입");
		
		System.out.println("sampleUserDetailDAO :" + sampleUserDetailDAO);
		
		MyUser user = null;
		
		
		//독자적인 인증 API 엑세스
		try {
			
			 user = sampleUserDetailDAO.checkUser(username);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
				
		
		//사용자가 존재하지 않는경우
		if(user == null) {
			throw new UsernameNotFoundException("해당 유저 이름이 존재하지 않습니다.");			
		}else {
			
			System.out.println("유저네임 존재");
		    System.out.println(user.getLoginId());
		}
		
		
		
	    //사용자명으로 비번취득
		String password = user.getPassword();
		
		//사용자명으로 부터 ROll 취득
		String rolename1 = "ROLE_USER";
		//String rolename2 = "ROLE_ADMIN";
		
		
		//GrantedAuthority의 Collection을 작성
		Set<GrantedAuthority> authorities = new HashSet<>();
		authorities.add(new SimpleGrantedAuthority(rolename1));
		//authorities.add(new SimpleGrantedAuthority(rolename2));
		
		
		return new User(username , password, authorities);
		
		
	}

	//파일 작성이 끝났다면 스프링 설정파일에 정의해줌.
	
	
}

 

✅ web.xml 작성

contextConfigLocation에 value 값으로 위에서 작성한 xml 파일을 순서대로 작성해주고, 아래 처럼 스프링 시큐리티 필터를 작성해 준다.

<?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/sql/sqlSessionFactory.xml,
			
						/WEB-INF/spring/beans-security-db.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>




	<!-- 스프링 Security 필터 -->
	<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>






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





</web-app>

 

 

✅ 예제 파일

Test3.zip
0.07MB