SpringBoot/스프링시큐리티

스프링 시큐리티 - 로그인 기능

공부 기록장 2024. 7. 16. 22:51

※순서

1. 스프링 시큐리티에 로그인 URL 등록하기___(SecurityConfig.java)

2. 회원 컨트롤러에 URL 매핑 추가하기______(UserController.java)

3. 로그인 화면 구현____________________(login_form.html)

4. 회원 리포지터리 수정하기_____________(UserRepository.java)

5. 권한 설정 파일 생성하기______________(UserRole.java)

6. UserSecurityService 서비스 생성하기

7. 스프링 시큐리티 설정 수정하기

8. 로그인 화면 수정하기

9. 로그아웃 기능 구현하기


 

1. 스프링 시큐리티에 로그인 URL 등록하기

 

SecurityConfig.java 에 다음 코드 추가

.formLogin((formLogin) -> formLogin
   .loginPage("/user/login")
   .defaultSuccessUrl("/"));

 

 

● .formLogin 메소드는 스프링 시큐리티의 로그인 설정을 담당하는 부분

● 로그인 페이지의 URL은 /user/login

● 로그인 성공 시에 이동할 페이지는 루트(/)

 


 

2. 회원 컨트롤러에 URL 매핑 추가하기

 

UserController.java 에 다음 코드 추가

@GetMapping("/user/login")
public String login() {
   return "login_form";
}

 


 

3. 로그인 화면 구현

 

login_form.html

<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-3">
  <form th:action="@{/user/login}" method="post">
    <div th:if="${param.error}">
       <div class="alert alert-danger">
           사 용 자ID 또 는 비 밀 번 호 를 확 인 해 주 세 요.
       </div>
     </div>
     <div class="mb-3">
         <label for="username" class="form-label">사 용 자ID</label>
         <input type="text" name="username" id="username" class="form-control">
     </div>
     <div class="mb-3">
         <label for="password" class="form-label">비 밀 번 호</label>
         <input type="password" name="password" id="password" class="formcontrol">
     </div>
     <button type="submit" class="btn btn-primary">로 그 인</button>
   </form>
</div>
</html>

4. 회원 리포지터리 수정하기

 

userRepository.java

package com.mysite.sbb.user;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<SiteUser, Long> {
    Optional<SiteUser> findByusername(String username);
}

 

사용자ID 를 조회하는 기능이 필요하므로 ID로 사용자 엔티티를 조회하는 findByusername 메소드가 필요

 


5. 권한 설정 파일 생성하기

 

UserRole.java

package com.mysite.sbb.user;
import lombok.Getter;

@Getter
public enum UserRole {
   ADMIN("ROLE_ADMIN"),
   USER("ROLE_USER");
  
   UserRole(String value) {
     this.value = value;
   }
   private String value;
}

ADMIN는 관리자, USER는 사용자를 의미한다. 그리고 ADMIN과 USER 상수는 값을 변경할 필요가 없으므로 @Getter만 사용하였다.

 


6. UserSecurityService 서비스 생성하기

 

UserSecurityService.java

package com.mysite.sbb.user;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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 lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class UserSecurityService implements UserDetailsService {
    private final UserRepository userRepository;
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
         Optional<SiteUser> _siteUser = this.userRepository.findByusername(username);
    if (_siteUser.isEmpty()) {
         throw new UsernameNotFoundException("사 용 자 를 찾 을 수 없 습 니 다.");
    }
    SiteUser siteUser = _siteUser.get();
    List<GrantedAuthority> authorities = new ArrayList<>();
    if ("admin".equals(username)) {
        authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue()));
    } else {
        authorities.add(new SimpleGrantedAuthority(UserRole.USER.getValue()));
    }
    return new User(siteUser.getUsername(), siteUser.getPassword(),authorities);
   }
}

 

스프링 시큐리티가 로그인 시 사용할 UserSecurityService 는 스프링 시큐리티가 제공하는 UserDetailsService 인터페이스를 구현해야한다.

 

사용자명이 admin 일 경우 ADMIN 권한을 부여하고

그 외에는 USER 권한을 부여한다.


 

7. 스프링 시큐리티 설정 수정하기

 

SecurityConfig.java

(... 생 략 ...)
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration
.AuthenticationConfiguration;
(... 생 략 ...)

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    (... 생 략 ...)
    @Bean
    AuthenticationManager authenticationManager(AuthenticationConfiguration
    authenticationConfiguration) throws Exception {
       return authenticationConfiguration.getAuthenticationManager();
    }
}

AuthenticationManager 는 사용자 인증 시 앞에서 작성한 UserSecurityService 와 PasswordEncoder 를 내부적으로 사용하여 인증과 권한 부여 프로세스를 처리한다.


8. 로그인 화면 수정하기

 

로그인 버튼에 th:href="@{/user/login}" 추가

 

sec:authorize="isAnonymous()" -> 로그인 버튼에 추가

sec:authorize="isAuthenticated()" -> 로그아웃 버튼에 추가


9. 로그아웃 기능 구현하기

 

SecurityConfig 파일에 다음 코드 추가

.logout((logout) -> logout
    .logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
    .logoutSuccessUrl("/")
    .invalidateHttpSession(true));