전체 방문자
오늘
어제
21종
종이의 코딩 공부방
21종
  • 분류 전체보기 (174)
    • JAVA (64)
    • Springboot (46)
      • 블로그만들기 (45)
    • Database (60)
      • Oracle (60)
    • 프로젝트 3 (CELOVER) (0)
    • 개발서버 구축 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

최근 댓글

hELLO · Designed By 정상우.
21종

종이의 코딩 공부방

Springboot/블로그만들기

[Springboot] 블로그 만들기 (24)_스프링 시큐리티(5)_로그인

2023. 11. 29. 15:50

loginForm.jsp

<form action="/auth/loginProc" method="post" >
    <div class="form-group">
        <label for="userName">UserName</label> 
        <input type="text" name="userName" class="form-control" placeholder="userName" id="userName">
    </div>
    <div class="form-group">
        <label for="pwd">Password</label> 
        <input name="password"  type="password" class="form-control" placeholder="password" id="password">
    </div>
<button id="btn-login" class="btn btn-primary">로그인</button>
</form>

 

SecurityConfig.java

// 빈 등록 : 스프링 컨테이너에서 객체를 관리할 수 있게 하는 것
@Configuration // 빈등록 (IoC관리)
// Controller 에 들어가기전에 여기를 탄다
public class SecurityConfig {

	@Bean
	// 사용자의 자격증명을 검증하는 Bean 생성
	public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
		return authenticationConfiguration.getAuthenticationManager();
	}

	@Bean // IoC가 된다!! 비밀번호를 해싱하는데 사용
	public BCryptPasswordEncoder encodePWD() {
		return new BCryptPasswordEncoder();
	}

	@Bean
	SecurityFilterChain configure(HttpSecurity http) throws Exception {
		http
			.csrf().disable() // csrf 토큰 비활성화 (테스트시 걸어두는게 좋음)
			.authorizeRequests()
				.antMatchers("/", "/auth/**", "/js/**", "/css/**", "/img/**") // "/auth/**", "/js/**", "/css/**", "/img/**" 에 대해서는
				.permitAll() // 모두 허용
				.anyRequest() // 다른 request에 대해서는
				.authenticated() // 인증이 필요해
			.and() // 그리고 인증이 필요한 곳에 대해서는 /auth/loginForm로 url 요청
				.formLogin()   
				.loginPage("/auth/loginForm")
				.loginProcessingUrl("/auth/loginProc") // 스프링 시큐리티가 해당 주소로 로그인을 가로채서 대신 로그인 해준다.
				.defaultSuccessUrl("/") // 성공시 이 페이지로 이동
				.usernameParameter("userName") // userDetails 에서는 파라미터명을 username인 것을 받아서 사용하는데 userName을 변경하겠다.
				//.failureUrl("/fail") // 실패시 이 페이지로 이동 
				;
		return http.build();
	}
}

 

PrincipalDetail.java

SpringSecurity의 고유세션 저장소에서는 UserDetail 객체를 사용하기 때문에 기존에 만든 User 객체를 스프링에 맞게 타입을 바꿔줘야 한다.

기존의 User객체를 UserDetails 타입으로 만들어야 한다.  

 

PrincipalDetail.java

// 스프링 시큐리티가 로그인 요청을 가로채서 로그인을 진행하고 완료가 되면 UserDetails 타입의 오브젝트를
// 스프링 시큐리티의 고유한 세션저장소에 저장을 해준다.
@Data
public class PrincipalDetail implements UserDetails{

	private User user; // 컴포지션(객체를 품고있음)
	
	public PrincipalDetail(User user) {
		this.user = user;
	}

	@Override
	public String getPassword() {
		return user.getPassword();
	}

	@Override
	public String getUsername() {
		return user.getUserName();
	}

	// 계정이 만료되지 않았는지 리턴한다 (true : 만료안됨)
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	// 계정이 잠겨있지 않았는지 리턴한다 (true : 잠기지 않음)
	@Override
	public boolean isAccountNonLocked() {
		return true;
	}
	
	// 비밀번호가 만료되지 않았는지 리턴한다 (true : 만료안됨)
	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	// 계정이 활성화(사용가능)인지 리턴한다 (true : 활성화)
	@Override
	public boolean isEnabled() {
		return true;
	}

	// 계정이 갖고있는 권한 목록을 리턴한다.(권한이 여러개 있을 수 있어서 루프를 돌아야하는데 우리는 한개만)
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		
		Collection<GrantedAuthority> collectors = new ArrayList<>();
		collectors.add(
				()->{
					return "ROLE_" + user.getRole();
					}
				);
		
		return collectors;
	}
}

 

PrincipalDetailService.java

@Service // Bean 등록
public class PrincipalDetailService implements UserDetailsService{
	
	@Autowired
	private UserRepository userRepository;
	
	// 스프링이 로그인 요청을 가로챌 때, userName, password 변수 2개를 가로채는데
	// password 부분처리는 알아서 함.
	// userName이 DB에 있는지만 확인해주면 됨.
	@Override
	public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
		User principal = userRepository.findByUserName(userName)
				.orElseThrow(()->{
					return new UsernameNotFoundException("해당 사용자를 찾을 수 없습니다. : " + userName);
				});
		return new PrincipalDetail(principal); // 시큐리티의 세션에 유저 정보가 저장이 됨.
	}
}

 

UserRepository.java

public interface UserRepository extends JpaRepository<User, Integer>{ 
	
	// SELECT * FROM user Where userName = 1?; 비밀번호검증은 SpringSecurity가 한다.
    // 우리는 userName이 실제로 DB에 있는지만 확인해서 넘겨주면 된다.
	Optional<User> findByUserName(String userName);
}

 

로그인이 잘된다.


참고 유튜브 (메타코딩님 강의)

https://youtu.be/pHp2LGuukls?si=us6jd9Q2YZCJtPfx

 

    'Springboot/블로그만들기' 카테고리의 다른 글
    • [Springboot] 블로그 만들기 (26)_글 목록 보기
    • [Springboot] 블로그 만들기 (25)_썸머노트를 이용한 글쓰기
    • [Springboot] 블로그 만들기 (23)_스프링 시큐리티(4)_비밀번호 해쉬, 회원가입
    • [Springboot] 블로그 만들기 (22)_스프링 시큐리티(3)_커스터마이징
    21종
    21종
    코딩 공부한 것 정리하려고 만든 블로그

    티스토리툴바