Spring

Spring STEP 12 - Spring Security 2

2023. 6. 21. 12:21
728x90

★ 회원가입

 

■ 파일 생성

com.test.controller > MemberController.java
com.test.mapper > MemberMapper.java(I)
com.test.domain > MemberDTO.java
                > AuthDTO.java

- src/main/resources > com > test > mapper > MemverMapper.xml

- views > register.jsp
        > registerok.jsp

 

■ 기초 셋팅

  • MemberMapper.xml
<?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.test.mapper.MemberMapper">

</mapper>
  • MemberDTO.java
import java.util.List;

import lombok.Data;

@Data
public class MemberDTO {

	private String userid;
	private String userpw;
	private String username;
	private String regdate;
	private String updatedate;
	private String enabled;
	
	private List<AuthDTO> authlist;
}
  • AuthDTO.java
import lombok.Data;

@Data
public class AuthDTO {
	private String userid;
	private String auth;
}
  • MemberController.java
@Controller
public class MemberController {

	@Autowired
	private MemberMapper mapper;
	
	@Autowired
	private PasswordEncoder encoder;

	@GetMapping("/register.do")
	public String register() {
		
		return "register";
	}
	
	@PostMapping("/registerok.do")
	public String registerok() {
		
		return "registerok";
	}
}
  • 스캔 추가 -> root-context.xml -> namespace -> mybatis -> 스캔추가
<mybatis-spring:scan base-package="com.test.mapper"/>

 

■ 회원가입 Form 만들기 -> register.jsp

<%@ include file="/WEB-INF/views/inc/header.jsp" %>

<h2>Register Page</h2>

<form method="post" action="/security/registerok.do">
    <table class="vertical">
        <tr>
            <th>아이디</th>
            <td><input type="text" name="userid" required></td>
        </tr>
        <tr>
            <th>암호</th>
            <td><input type="password" name="userpw" required></td>
        </tr>
        <tr>
            <th>이름</th>
            <td><input type="text" name="username" required></td>
        </tr>
        <tr>
            <th>권한</th>
            <td>
                <select name="auth">
                    <option value="1">일반회원</option>
                    <option value="2">관리자</option>					
                </select>
            </td>
        </tr>
    </table>
    <div>
        <input type="submit" value="등록하기">
    </div>
    <!-- CSRF 토큰 -->
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}">
</form>

 

■ 회원 가입 처리 -> MemberController.java

----------------- MemberController.java---------------------
@PostMapping("/registerok.do")
public String registerok(Model model, MemberDTO dto, int auth) {

    //암호 인코딩
    dto.setUserpw(encoder.encode(dto.getUserpw()));

    int result = mapper.register(dto);
    
    if (auth >= 1) {
        AuthDTO adto = new AuthDTO();
        adto.setUserid(dto.getUserid());
        adto.setAuth("ROLE_MEMBER");
        mapper.registerAuth(adto);
    }
    
    if (auth >= 2) {
        AuthDTO adto = new AuthDTO();
        adto.setUserid(dto.getUserid());
        adto.setAuth("ROLE_ADMIN");
        mapper.registerAuth(adto);
    }

	model.addAttribute("result", result);

    return "registerok";
}
------------------- MemberMapper.java -----------------------
int register(MemberDTO dto);
void registerAuth(AuthDTO adto);
------------------- MemberMapper.xml ------------------------
<insert id="register">

    insert into tbl_member(userid, userpw, username) values (#{userid}, #{userpw}, #{username})

</insert>

<insert id="registerAuth">
    insert into tbl_member_auth(userid, auth) values (#{userid), #{auth})
</insert>

 

■ registerok.jsp

<%@ include file="/WEB-INF/views/inc/header.jsp" %>

<h2>Register OK Page</h2>

<div>${result}</div>

 

★ UserDetailService > 커스텀 UserDetailService

- 여태까지.. username(id), userpassword, enabled, authority
- 추가로 관리하고 싶은 정보가 있으면 직접 UserDetailsService를 구현
  • index.jsp -> 태그 추가
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
  • 우리가 가져오고 싶은 정보 > SQL
1. MemberDTO
2. AuthDTO
3. MemberMapper(I)
4. MemberMapper.xml
  • MemberMapper.xml -> select 작성
<resultMap type="com.test.domain.MemberDTO" id="memberMap">
  <id property="userid" column="userid" />
  <result property="userid" column="userid" />
  <result property="userpw" column="userpw" />
  <result property="username" column="username" />
  <result property="enabled" column="enabled" />
  <result property="regdate" column="regdate" />
  <result property="updatedate" column="updatedate" />
  <collection property="authlist" resultMap="authMap"></collection>
</resultMap>

<resultMap type="com.test.domain.AuthDTO" id="authMap">
  <result property="userid" column="userid" />
  <result property="auth" column="auth" />
</resultMap>

<select id="read" resultMap="memberMap">
  select
     m.userid,
     m.userpw,
     m.username,
     m.enabled,
     m.regdate,
     m.updatedate,
     a.auth
  from tbl_member m
     left outer join tbl_member_auth a
        on m.userid = a.userid
           where m.userid = #{userid}
</select>

 

■ 파일 생성

src/test/java > "com.test.mapper" > MapperTest.java
  • 코드작성
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class MapperTest {

	@Autowired
	private MemberMapper mapper;
	
	@Test
	public void testRead() {
		
		MemberDTO dto = mapper.read("dong");
		
		log.info(dto);
		
		dto.getAuthlist().forEach(adto -> log.info(adto));
		
	}
}

 

■ CustomUserDetailServie 구성

- com.test.auth > "CustomUserDetailsService.java"
- com.test.domain > "CustomUser.java"
  • 코드 작성
@Log4j
public class CustomUserDetailsService implements UserDetailsService {@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		//기본 > username, password, enabled, authority
		//재정의 > 기본 + 추가 정보
	
		return null;
	}

}
  • Security-context.xml -> bean 추가 
<!-- 유저 정보 객체 -->
<bean id="customUserDetailsService" class="com.test.auth.CustomUserDetailsService"></bean>
  • Security-context.xml -> security 추가
<security:authentication-manager>
    <security:authentication-provider user-service-ref="customUserDetailsService">
        <security:password-encoder ref="bcryptPasswordEncoder"/>
    </security:authentication-provider>
</security:authentication-manager>
  • CustomUser.java -> 코드 작성
@Getter
public class CustomUser extends User {

	public MemberDTO member;
	
	public CustomUser(String username, String password
            , Collection<? extends GrantedAuthority> authorities) {
      super(username, password, authorities);
   }
   
   public CustomUser(MemberDTO dto) {
	   
	   //MemberDTO > Customer(User)
      
      super(dto.getUserid(), dto.getUserpw(), dto.getAuthlist().stream().map(auth -> new SimpleGrantedAuthority(auth.getAuth())).collect(Collectors.toList()));
      
      this.member = dto;
   }
	
}

 

■ info -> 만들기

  • MemberController.java -> 추가
@GetMapping("/info.do")
public String info() {

    return "info";
}
  • info.jsp
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>  

<%@ include file="/WEB-INF/views/inc/header.jsp" %>

<h2>Info Page</h2>

<div class="message" title="principal">
    <sec:authentication property="principal"/>
</div>

<div class="message" title="MemberDTO">
    <sec:authentication property="principal.member"/>
</div>

<div class="message" title="사용자 아이디">
    <sec:authentication property="principal.username"/>
</div>

<div class="message" title="사용자 아이디">
    <sec:authentication property="principal.member.userid"/>
</div>

<div class="message" title="사용자 이름">
    <sec:authentication property="principal.member.username"/>
</div>

<div class="message" title="사용자 권한">
    <sec:authentication property="principal.member.authlist"/>
</div>
  • 결과

 

■ 스프링 시큐리티 > JSP 페이지 + 권한 적용 > 스프링 시큐리티 표현식

  • hasRole()
  • isAnonymous()
  • isAuthenticated()
  • header.jsp -> 작업
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>  

<!-- header.jsp -->
<header>
	<h1>Spring Security</h1>
	<ul>
		<li><a href="/security/index.do">Index</a></li>
		
		<sec:authorize access="hasRole('ROLE_MEMBER')">
		<li><a href="/security/member.do">Member</a></li>
		</sec:authorize>
		
		<sec:authorize access="hasRole('ROLE_ADMIN')">
		<li><a href="/security/admin.do">Admin</a></li>
		</sec:authorize>
		<li class="divider"></li>
		
		<sec:authorize access="isAnonymous()">
		<li><a href="/security/customlogin.do">Login</a></li>
		<li class="divider"></li>	
		<li><a href="/security/register.do">Register</a>
		</sec:authorize>
		
		<sec:authorize access="isAuthenticated()">
		<li><a href="/security/customlogout.do">Logout</a></li>
		<li class="divider"></li>
		<li><a href="/security/info.do">Info</a>
		</sec:authorize>
		
		
		
	</ul>
</header>

 

★ 자동 로그인(Remember-me)

  • 스프링 시큐리티에 기본으로 탑재
  • 정해진 테이블 구현
  • DB 생성
create table persistent_logins (
   username varchar(64) not null,
   series varchar(64) primary key,
   token varchar(64) not null,
   last_used timestamp not null
);
  • Security-context.xml -> 자동로그인 설정
<!-- 자동 로그인 -->
<security:remember-me data-source-ref="dataSource" token-validity-seconds="8640000" />
728x90
저작자표시 비영리 변경금지 (새창열림)

'Spring' 카테고리의 다른 글

Spring STEP 13 - Board 2  (0) 2023.06.22
Spring STEP 13 - Board  (0) 2023.06.21
Spring STEP 11 - Spring Security  (0) 2023.06.20
Spring STEP 10 - MyBatisSimple  (0) 2023.06.19
Spring STEP 9 - AOP  (0) 2023.06.19
'Spring' 카테고리의 다른 글
  • Spring STEP 13 - Board 2
  • Spring STEP 13 - Board
  • Spring STEP 11 - Spring Security
  • Spring STEP 10 - MyBatisSimple
IT의 큰손
IT의 큰손
IT계의 큰손이 되고 싶은 개린이의 Log 일지
IT의 큰손
Developer Story House
IT의 큰손
전체
오늘
어제
  • 분류 전체보기 (457)
    • 정보처리기사 필기 (18)
    • 정보처리기사 실기 (12)
    • 정보처리기사 통합 QUIZ (12)
    • 빅데이터 (11)
    • 안드로이드 (11)
    • 웹페이지 (108)
    • 자바 (49)
    • SQLD (3)
    • 백준 알고리즘 (76)
    • 데이터베이스 (41)
    • 깃허브 (2)
    • Library (14)
    • Server (31)
    • 크롤링&스크래핑 (3)
    • Spring (23)
    • Vue.js (13)
    • React (27)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Developer Stroy House

인기 글

태그

  • 개발자
  • 웹개발
  • jquery
  • it
  • 프론트엔드
  • 웹페이지
  • 백준
  • 정보처리기사필기
  • IT개발자
  • 백엔드
  • 데이터베이스
  • css
  • React
  • ajax
  • IT자격증공부
  • 자바
  • 웹개발자
  • DB
  • 정보보안전문가
  • IT자격증
  • JavaScript
  • 알고리즘
  • java
  • 코딩테스트
  • html
  • 개발블로그
  • jsp
  • 정보처리기사
  • DBA
  • 앱개발자

최근 댓글

최근 글

Designed By hELLO
IT의 큰손
Spring STEP 12 - Spring Security 2
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.