Springboot - Security (4) 시큐리티 로그인

Yuri Lee·2020년 9월 17일
0

Springboot - Security

목록 보기
4/8

이 챕터는 추후보충 필요

loginProcessingUrl("/login");

// /login 주소가 호출되면 시큐리티가 낚아채서 대신 로그인을 진행해준다. 그렇기 때문에 컨트롤러에 /login을 만들지 않아도 된다.

<form action= "/login" method="POST">

username, password로 /login으로 이동을 하면 시큐리티가 낚아채서 로그인을 진행하는데 이때 몇가지 해줘야 할일들이 있다.

  1. auth 패키지 만들기

auth 패키지를 만들고 PrincipalDetails.java 를 만들어준다. 이것을 만든 이유가 무엇일까?

시큐리티가 /login 주소 요청이 오면 낚아채서 로그인을 진행시킨다. 로그인 진행이 완료가 되면 seesion을 만들어준다. 그중에서도 시큐리티가 갖고 있는 세션이 있다. 자신만의 세션 공간을 가진다. Security ContextHolder 라는 키 값에다가 세션 정보를 저장시킨다. 이때 들어갈 수 있는 정보는 시큐리티가 가지고 있는, 세션에 들어갈 수 있는 오브젝트가 정해져 있다.

Authentication 객체, 이 타입의 객체여야 한다. 이 객체 안에는 무엇이 있을까? 이 안에는 User 정보가 있어야 한다.

User 오브젝트의 타입은 UserDetais 타입의 객체여야 한다. 쉽게 말하자면 시큐리티 세션에다가 정보를 저장해야 한다. 이때 Authentication 객체가 들어가야 한다. 그리고 이 안에 유저 정보를 저장할때 UserDetails 타입이어야 한다.

그래서 나중에 꺼냈을 때

Security Session 에 있는 것을 세션 정보를 get 해서 꺼내면 Authentication 객체가 나온다. 이 안에서 UserDetails 를 꺼내면 User 오브젝트에 접근할 수 있다. 어떻게 얘를 꺼내면 User 오브젝트에 접근할 수 있을까?..

PrincipalDetails 가 UserDetails implements 한다. 그러면 PrincipalDetails가 UserDetails 이 될 것이다.

그럼 PrincipalDetails는 UserDetails와 같은 타입이 되는 것이다. 그러면 이 PrincipalDetails를 Authentication 객체 안에 넣을 수 있다.

그 다음에 오버라이드..

PrincipalDetails를 넣기 위해서는 Authentication 객체를 만들어야 한다.

PrincipalDetailsService.java

package com.yuri.security1.config.auth;

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;

// 시큐리티 설정에서 loginProcessingUrl("/login");
// login 요청이 오면 자동으로 UserDetailsService 타입으로 IoC 되어 있는 loadUserByUsername 함수가 실행됨 (규칙임)
@Service //서비스로 띄어주기 
public class PrincipalDetailsService implements UserDetailsService{

	@Override // (String username) 이게 무엇일까..?
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		return null;
	}

}

(String username) 이게 무엇일까..? 굉장히 중요한데..
우리가 로그인을 할때 파라미터로 넘어가는 username, password

loginForm.html

<form action= "/login" method="POST">
	<input type="text" name="username" placeholder="Username"/> <br/>
	<input type="password" name="password" placeholder="Password"/> <br/>
	<button>login</button>
</form>

만약 내가 이것을 username2라고 했으면 loadUserByUsername(String username) 여기서 받아지지 않는다.

내가 login 버튼을 클릭하면 action의 /login이 발동을 한다. 그럼 스프링은 IoC 컨테이너에서 UserDetailsService로 등록되어 있는 타입을 찾는다. 그럼 PrincipalDetailsService를 찾게 될 것이다. 얘가 찾아지면 바로 loadUserByUsername 함수를 호출한다. 그때 넘어온 파라미터 username값을 가져온다. 그럼 여기서 무엇을 하면 되는가...!

@Autowired를 한다.

저 이름을 user가 있는지 확인을 해야 한다.

findByUsername 이런 함수는 userRepository가 들고 있지 않는다. 기본적인 CRUD만 들고 있기 때문이다. username으로 user를 검색하려면 UserRepository에다가 하나 더 만들어야 한다.

UserRepository.java

정리
시큐리티 세션 내부에 Authentication 객체가 들어가고 Authentication 객체는 내부에 UserDetails를 들고 있다. 이렇게 하면 로그인이 완료된다.


[Reference]

이 글은 유투버 데어 프로그래밍의 스프링 부트 시큐리티 강좌를 바탕으로 정리한 내용입니다.

profile
Step by step goes a long way ✨

0개의 댓글