본문 바로가기
국비학원/수업기록

국비 지원 개발자 과정_Day102

by 루팽 2023. 4. 25.

<스프링 시큐리티 복습 진행중 - PrincipalDetailsService.java>

package com.example.demo.auth;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.example.demo.dao.UserDao;
import com.example.demo.model.User;
/*
 * 왜 굳이 Service계층을 따로 관리하는가?
 * 로그인 처리를 빼앗겼다 - 제어권이 스프링에게 있음 - IoC - 제어역전, 역제어
 * 스프링 시큐리티 - filter chain - 
 * 보안상 세션관리 따로 진행함
 * Authentication은 UserDetails타입만 받아 준다
 * <bean class="구현체클래스" type="추상클래스 or 인터페이스"/>
 */
@Service
public class PrincipalDetailsService implements UserDetailsService {
	Logger logger = LogManager.getLogger();
	
	@Autowired //제어권이 스프링 컨테이너에게 있다 - ApplicationContext - 영속성
	private UserDao userDao = null;
	
	//loadUserByUsername메소드를 재정의해야 하기때문이다 
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		logger.info(username);//사용자가 입력한 이름
		//User타입은 Authentication에 직접 담을 수 없음
		//User타입을 UserDetails타입에 담아줌
		User ruser = userDao.login(username);
		if(ruser !=null) {
			return new PrincipalDetails(ruser);
		}
		return null;
	}
}

 

<스프링 시큐리티 복습 진행중 - PrincipalDetails.java>

package com.example.demo.auth;

import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.example.demo.model.User;
import lombok.Data;

//여기에서 쥔 값을 세션에 담아야 함
@Data
public class PrincipalDetails implements UserDetails {
	private static final long serialVersionUID = 1L;
	private User user;
	
	//일반 로그인시 사용하는 생성자
	public PrincipalDetails(User user) {
		this.user = user;
	}
	
	//OAuth로그인시 사용하는 생성자 따로 정의함
	//해당 User권한을 리턴하는 곳
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		Collection<GrantedAuthority> collect = new ArrayList<>();
		collect.add(new GrantedAuthority() {
			@Override
			public String getAuthority() {
				return user.getRole();
			}
		});
		return collect;
	}
	
	//데이터베이스와 매칭이 안되면 로그인 실패 페이지 호출됨
	@Override
	public String getPassword() {
		return user.getPassword();
	}

	@Override
	public String getUsername() {
		return user.getUsername();
	}
	
	//강제는 아니나 사용자가 세션에 담고 싶은 다른 컬럼정보도 등록이 가능함
	public String getRole() {
		return user.getRole();
	}
	
	public String getCreateDate() {
		return user.getCreateDate();
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}
}

 

<스프링 시큐리티 복습 진행중 - HomeController.java>

package com.example.demo.controller;

import javax.servlet.http.HttpSession;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.demo.auth.PrincipalDetails;
import com.example.demo.logic.UserLogic;
import com.example.demo.model.User;

@Controller
public class HomeController {
	Logger logger = LogManager.getLogger(HomeController.class);
	
	@Autowired
	private UserLogic userLogic = null;
	
	@Autowired
	public BCryptPasswordEncoder bCryptPasswordEncoder = null;
	
	// user-123 admin-123
	@GetMapping("/")
	public String index(Authentication authentication, HttpSession session) {
		logger.info("index");
		PrincipalDetails principalDetails = null;
		if(authentication !=null) {
			principalDetails = (PrincipalDetails)authentication.getPrincipal();
			logger.info(principalDetails.getUser());	
			logger.info(principalDetails.getUser().getId());	
			logger.info(principalDetails.getUser().getEmail());	
			logger.info(principalDetails.getUser().getCreateDate());	
			logger.info(principalDetails.getUser().getUsername());	
			logger.info(principalDetails.getUser().getPassword());	
			logger.info(principalDetails.getUser().getRole());	
			session.setAttribute("email", principalDetails.getUser().getEmail());
			session.setAttribute("role", principalDetails.getUser().getRole());
			
		}
		return "forward:index.jsp";
	}
	
	// 로그인 화면
	@GetMapping("/loginForm")
	public String loginForm() {
		logger.info("loginForm");
		return "forward:loginForm.jsp";
	}

	// 로그인 에러 화면
	@GetMapping("/login-error")
	public String loginError() {
		logger.info("loginError");
		return "forward:loginError.jsp";
	}
	
	// 회원가입 화면
	@GetMapping("/joinForm")
	public String joinForm() {
		logger.info("joinForm");
		return "forward:joinForm.jsp";
	}
	
	// 회원가입
	@PostMapping("/join")
	public String join(User user) {
		logger.info("join");
		int result = 0; // 등록 성공 유무 담기
		user.setRole("ROLE_USER");
		// 패스워드 암호화처리
		String rawPassword = user.getPassword();
		String encPassword = bCryptPasswordEncoder.encode(rawPassword);
		user.setPassword(encPassword);
		result = userLogic.memberInsert(user);
		return "forward:loginForm.jsp";
	}
	
	// 유저 화면
	@GetMapping("/user")
	public String userPage() {
		logger.info("userPage");
		return "forward:user-index.jsp";
	}
	
	// 관리자 화면
	@GetMapping("/admin")
	public String adminPage() {
		logger.info("adminPage");
		return "forward:admin-index.jsp";
	}
}

 

<스프링 시큐리티 복습 진행중 - UserDao.java>

package com.example.demo.dao;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.example.demo.model.User;

@Repository
public class UserDao {
	Logger logger = LogManager.getLogger(UserDao.class);
	
	@Autowired
	private SqlSessionTemplate sqlSessionTemplate;
	
	public int memberInsert(User user) {
		logger.info("memberInsert");
		int result = 0;
		result = sqlSessionTemplate.update("memberInsert", user);
		return result;
	}
	
	public User login(String username) {
		logger.info("login");
		User user = null;
		user = sqlSessionTemplate.selectOne("login", username);
		return user;//PrincipalDetails에 담길 객체
	}
}

 

<스프링 시큐리티 복습 진행중 - member.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.example.demo">
	<!-- 회원 정보 입력 -->
	<insert id="memberInsert" parameterType="map">
		INSERT INTO member202210(
						  id
						, username
						, password
						, email
						, role
						, createDate
						)
		VALUES (SEQ_MEMBER202210_ID.nextval
					<if test="username != null">
						,#{username}
					</if>
					<if test="password != null">
						,#{password}
					</if>
					<if test="email != null">
						,#{email}
					</if>
					<if test="role != null">
						,#{role}
					</if>
						, to_char(sysdate, 'YYYY-MM-DD')
					)
	</insert>

	<!-- 로그인 -->
	<select id="login" parameterType="string" resultType="com.example.demo.model.User">
		SELECT id, username, password, role, email, createdate
		  FROM member202210
		 WHERE username = #{value}
	</select>
	
	<!-- 목록 출력 -->
	<select id="memberList" parameterType="map" resultType="map">
		select mem_uid, mem_name, mem_email 
		      ,mem_no, mem_nickname, mem_status, mem_auth
		  from member230324
		<where>
			<if test='mem_uid!=null and mem_uid.length()>0'>
				AND mem_uid = #{mem_uid}
			</if>
	<!-- 
	<input type=text id="mem_nickname" value=""/>
	항상 무조건 빈문자열이다. 폼전송하면 무조건 빈문자열이 있는 상태이다 
	너가 아무것도 입력하지 않아도  null에 걸리지 않는다 
	잡아내려면 문자열이 > 0 까지를 비교해야 잡아낼수 있다 
	 -->		
			<if test='MEM_NICKNAME!=null and MEM_NICKNAME.length()>0'>
				AND mem_nickname = #{MEM_NICKNAME}
			</if>
			<if test='mem_name!=null and mem_name.length()>0'>
				AND mem_name = #{mem_name}
			</if>
			<if test='mem_tel!=null and mem_tel.length()>0'>
				AND mem_tel = #{mem_tel}
			</if>
		</where>
	</select>
</mapper>

 

<스프링 시큐리티 복습 진행중 - PrincipalOauth2UserService.java>

package com.example.demo.oauth;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

//구글로그인버튼 -> 구글로그인창 -> 로그인을 완료 -> 코드를 리턴
//AccessToken요청 -> loadUser호출 -> 구글 프로필정보 받음

@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
	Logger logger = LogManager.getLogger(PrincipalOauth2UserService.class);
	
	@Override
	public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
		logger.info(userRequest);
		logger.info("구글발급해준 토큰 : "+userRequest.getAccessToken().getTokenValue());
		return super.loadUser(userRequest);
	}
}

 

<스프링 시큐리티 복습 진행중 - MainController.java>

package com.example.demo.controller;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/main/*")
public class MainController {
	Logger logger = LogManager.getLogger(MainController.class);
	
	@GetMapping("index")
	public String index() {
		logger.info("index");
		return "redirect:index.jsp";
	}
}

댓글