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 |