[스프링부트 블로그 만들기] 비밀번호 해쉬화(암호화), 스프링 시큐리티 로그인 구현하기
my code archive
article thumbnail
반응형

🤍스프링 시큐리티 구현하기

  • 스프링 시큐리티는 스프링 기반의 애플리케이션(인증, 권한, 인가 등)을 담당하는 스프링 하위 프레임워크임.

1. 인증이 안 된 사용자들이 출입할 수 있는 /auth/ 경로를 UserController에 추가해 준다.

 

2. 요청이 들어왔을 때 인증이 필요한지, 필요하지 않은지 구분하는 시큐리티 필터를 등록하는 SecurityConfig 클래스 생성

3. 설정 후 localhost:8080 주소로 접근하면 아래와 같은 화면이 뜨지만

 

4. 인증없이 접근할 수 있도록 설정해놓은 /auth/ 주소로 접속하면 페이지가 잘 뜨는 것을 확인할 수 있다.

5. 기존에 작성한 loginForm.jsp에서 form태그를 수정한다.

<form action="/auth/loginProc" method="post">

 

6.SecurityConfig 코드를 아래와 같이 수정하면 위의 form태그에 걸어놓은 /auth/loginProc 주소를 UserApiController에 따로 매핑해줄 필요가 없다.

 

🤍비밀번호 해쉬(암호화) 구현하기

 

1. 시큐리티가 갖고 있는 함수 사용

2. JUnit 테스트 코드 작성

아래와 같이 암호화가 되는 것을 확인할 수 있다.

 

3. UserService에 암호화 코드 작성

 

4. DB를 초기화하고 다시 회원가입을 해보면 해쉬화된 비밀번호가 잘 들어간 것을 확인할 수 있다.

💡XSS & CSRF 차이점

  • 웹사이트 취약점 공격의 하나로 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제 등)를 특정 웹사이트에 요청하게 하는 공격.
  • XSS를 이용한 공격은 사용자가 특정 웹사이트를 신용하는 점을 노린 것.
  • CSRF는 특정 웹사이트가 사용자의 웹 브라우저를 신용하는 상태를 노린 것.
  • 대응 방안 : CSRF 토큰 사용, 사용자와 상호 처리 기능 적용, 재인증 요구
  • XSS는 공격 대상이 클라이언트, CSRF는 서버이다.

🤍스프링 시큐리티 로그인 구현하기

1. PrincipalDetail 작성

  • 로그인폼에서 완료 버튼을 누르면 form submit으로 username, password를 넘겨준다.
  • SecurityConfig 클래스에서 로그인 가로채고 진행함.
  • 스프링시큐리티가 로그인 요청을 가로채서 로그인 진행하고 완료가 되면 UserDetails 타입의 오브젝트(PrincipalDetail)를 스프링 시큐리티의 고유한 세션 저장소에 저장해준다.
@Getter
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 : 만료 안됨 / false : 만료됨)
	@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(new GrantedAuthority() {
			
			//@Override
			//public String getAuthority() {
				//스프링에서 ROLE을 받을 때 규칙임. ROLE_ 꼭 넣어줘야함.
				//return "ROLE_"+user.getRole();
			//}
		//});
		
		collectors.add(()->{return "ROLE_"+user.getRole();});
		
		return collectors;
	}
}

 

2. PrincipalDetailService 작성

  • 스프링이 로그인 요청을 가로챌 때 username, password 변수 2개를 가로채는데 password부분 처리는 알아서함.
  • username이 DB에 있는지만 확인해서 return해주면 됨.

 

3. username 찾는 메서드  UserRepository에 작성

//SELECT * FROM  user WHERE username = ?
	Optional<User> findByUsername(String username);

 

💡다시 정리

  • 로그인 요청이 오는 순간 '/auth/loginProc' 주소를 SecurityConfig가 가로챔.
  • 그 다음 PrincipalDetailService가 갖고 있는 메서드에서 username이 있는지 비교 후 new PrincipalDetail(principal)를 리턴함.
  • 리턴할 때 아래 코드를 통해 사용자가 적은 비밀번호와 DB를 비교해서 비밀번호를 암호화한다.

  • 비교가 끝나면 principal 객체에 저장이 됨.

4. 로그인이 잘 된다.

반응형
profile

my code archive

@얼레벌레 개발자👩‍💻

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

반응형