Spring Security 간단한 사용법

수정이·2022년 7월 13일
0

Spring

목록 보기
7/16
post-thumbnail
post-custom-banner

스프링 시큐리티 스타터 설정

  • 스프링 시큐리티를 사용하기 위해서는 먼저 스타터를 설정해야한다.
    • 프로젝트를 생성할 때 미리 설정하거나
      Maven Repository에서 스프링 시큐리티를 찾아서 의존 설정을 해주면 된다.
    • 예시(Maven)
      <dependency>
      	<groupId>org.springframework.boot</groupId>
      	<artifactId>spring-boot-starter-security</artifactId>
      </dependency>
      <dependency>
      	<groupId>org.springframework.security</groupId>
      	<artifactId>spring-security-test</artifactId>
      	<scope>test</scope>
      </dependency>
  • 스타터를 설정하면 자동설정 클래스들이 동작한다.
    • http://localhost:8080을 입력하면 시큐리티가 만든 로그인 폼이 보인다.
    • 시큐리티가 만든 계정의 비밀번호가 콘솔에 표시되는데 이때 아이디는 user이다.

시큐리티 커스터마이즈 하기

@Configuration
@EnableWebSecurity
public class TestWebMvcConfiguration extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 다음 경로에 대한 요청은 인증 없이 접근을 허용하도록 설정한다.
		http.authorizeRequests().antMatchers("/", "/auth/**", "/js/**", "/image/**", "/webjars/**").permitAll();

		// 위에서 언급한 경로 외에는 모두 인증을 거치도록 설정한다.
		http.authorizeRequests().anyRequest().authenticated();

		// 시큐리티가 제공하는 기본 로그인 화면은 CSRF 토큰을 무조건 전달한다.
		// 하지만 사용자 정의 로그인 화면에서는 CSRF 토큰을 전달하지 않는다.
		http.csrf().disable();

		// 사용자가 만든 로그인 화면을 띄운다.
		http.formLogin().loginPage("/auth/login");

		// 로그아웃 설정
        http.logout().logoutUrl("/auth/logout").logoutSuccessUrl("/");
	}
}
  • @EnableWebSecurity 어노테이션과 WebSecurityConfigurerAdapter를 상속한 환경설정 클래스를 만들어 자동설정된 클래스들을 해제하고 커스터마이즈 할 수 있다.
  • configure함수 안에 있는 메소드들을 통해 시큐리티 설정을 커스텀할 수 잇다.

DB와 연결하여 저장된 계정으로 로그인하기

@Getter
@Setter
public class UserDetailsImpl implements UserDetails {
	
	// User 엔티티 타입의 참조변수 선언
	private User user;
	
	public UserDetailsImpl(User user) {
		this.user = user;
	}

	// User Entity가 가지고 있는 권한 목록을 저장하여 리턴한다.
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		// 권한 목록을 저장할 컬렉션
		Collection<GrantedAuthority> roleList = new ArrayList<>();
		
		// 권한 설정
		roleList.add(new GrantedAuthority() {
			
			@Override
			public String getAuthority() {
				return "ROLE_" + user.getRole();
			}
		});
		
		return roleList;
	}

	@Override
	public String getPassword() {
		// {noop}은 비밀번호를 암호화하지 않도록 하는 접두사다.
		return "{noop}" + user.getPassword();
	}

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

	// 계정이 만료됐는지 여부를 리턴한다.
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	// 계정이 잠겨있는지 여부를 리턴한다.
	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	// 비밀번호가 만료됐는지 여부를 리턴한다.
	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	// 계정의 활성화 여부를 리턴한다.
	@Override
	public boolean isEnabled() {
		return true;
	}
}
  • UserDetails를 상속받아 오버라이드한 메소드를 설정하여 DB에 저장된 계정으로 로그인할 수 있다.
  • 정확히는 다음 과정까지 거쳐야 완벽하게 로그인 할 수 있다.
  • UserDetails는 입력받은 User객체가 정상 로그인 할 수 있는지 확인하는 클래스이다.

JPA와 연결하기

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

	@Autowired
	private UserRepository userRepository;
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		User principal = userRepository.findByUsername(username).get();
		return new UserDetailsImpl(principal);
	}

}
  • UserDetailsService를 상속받은 클래스를 활용한다.
  • JPA를 사용하여 DB에 저장된 User객체를 받고, 받은 User객체를 UserDetails를 상속받은 클래스에 넣어주고 결과를 리턴받으면 된다.

완성

	@Autowired
	private UserDetailsServiceImpl userDetailsService;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService);
	}
  • 처음에 만들었던 설정 클래스에 다음과 같은 코드를 추가하여 로그인을 완성시켜 주면 된다.
post-custom-banner

0개의 댓글