[TIL]241104 Spring Security, RestTemplate

MONA·2024년 11월 4일

나혼공

목록 보기
25/92

Spring Security

  • spring에서 모든 호출은 DispathcerServlet을 통과한다. 이후 매칭되는 Controller로 분배된다.
  • 그 이전에 모든 요청이 거쳐야 할 단계가 있다면 Filter를 활용하여 공통 처리 부분을 수행한다.
  • Spring Security는 FilterChainProxy를 통해 상세로직을 구현한다.
  • Spring Securiy는 Controller 앞단에 위치하여 인증, 인가를 수행한다.
    • 성공 시 Session 생성, UserDetails 객체 반환
    • 실패 시 로그인 페이지 반환

Form Login Authentication

  • 인증이 필요한 url이 들어왔을 때, 로그인이 되어있지 않다면 로그인 페이지를 반환한다.

UsernamePasswordAuthenticationFilter

  • Form login 기반을 사용할 때, password를 받아 인증 처리하는 필터
  • 순서
    • 사용자가 username과 password를 제출한다
    • 이를 기반으로 UsernamePasswordAuthenticationToken을 만들어 AuthenticationManager에 보내 인증을 시도한다
    • 성공시 SecurityContextHolder에 저장한다(그 외 다른것도 있음)

SecurityContextHolder의 구조

  • 내부에 SecurityContext가 있고 그 내부에 authentication이 있음
  • authentication: principal, credentails, authorities가 있음
// 예시코드
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
context.setAuthentication(authentication); // SecurityContext 에 인증 객체 Authentication 를 저장합니다.

SecurityContextHolder.setContext(context);

Authenticaion

  • principal: 사용자 식별. 주로 UserDetails 인스턴스 넣음
  • credentials: 주로 비밀번호. 사용자 인증에 사용하고 바로 삭제
  • authorities: 사용자에게 부여한 권한을 GrantedAuthority로 추상화하여 사용.
<UserDetails>
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    UserRoleEnum role = user.getRole();
    String authority = role.getAuthority();

    SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authority);
    Collection<GrantedAuthority> authorities = new ArrayList<>();
    authorities.add(simpleGrantedAuthority);

    return authorities;
}

Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());

UserDetailsService

  • username/password 인증방식 사용 시 사용자를 조회, 검증 후 UserDetails 반환
  • 커스텀하여 Bean 등록 후 사용 가능
  • UserDetails: UsernamePasswordAuthenticationToken 타입의 Authentication 생성 시 사용됨. 이 인증객체는 SecurityContextHolder에 세팅됨. 커스텀 사용 가능

Spring Security JWT 로그인

// 기본 설정인 Session 방식은 사용하지 않고 JWT 방식을 사용하기 위한 설정
        http.sessionManagement((sessionManagement) ->
                sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        );

위의 설정으로 기존의 Session 방식이 아닌 JWT 방식을 사용할 수 있다

Spring Security 방식을 사용해서 인증/인가를 진행함으로서 비즈니스로직에서 해당 부분을 분리할 수 있다.

접근 불가 페이지 만들기(권한별 접근 페이지 설정)

  • 유저 권한을 관리하는 Enum 클래스에서 생성 가능.
  • 권한 이름 명명 규칙 : “ROLE_”로 시작해야 함.

Spring Security로 권한 제어하기

  • controller의 메서드에 @Secured 어노테이션을 추가한다. ex) @Secured(”권한명”)
    • 여러 권한을 설정할 수 있다.
    • @Secured 어노테이션 활성화는 WebSecurityConfig에서 @EnableGlobalMethodSecurity(securedEnabled = true)를 설정해야 한다.

Validation

  • 데이터 검증을 원하는 객체 앞에 @Valid 어노테이션을 추가해 데이터 검증을 수행할 수 있다.
  • 해당 Dto의 각 필드에 대해 NotBlank, Email, Size, Max, Min 등 설정을 통해 유효한 데이터가 들어오는 지 검증할 수 있다.
  • Spring에서의 Validation 사용

Spring Boot에서의 Validation

정규표현식

  • ^ : 패턴의 시작

  • $ : 패턴의 종료

  • a-zA-Z : 모든 문자

  • 0-9 : 모든 숫자

  • ex) 이메일 정규 표현식: “^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$”

    • A-Za-z0-9: 모든 문자
    • ._%+- : 이메일의 사용자명에 포함될 수 있는 특수문자
    • [A-Za-z]{2,} : 두 글자 이상의 알파벳 대소문자로 이루어진 TLD
  • 휴대전화 정규 표현식: “^\d{3}-\d{4}-\d{4}$”

    • \d{n} : n자리 숫자
  • \w과 A-Za-z0-9의 차이

    • \w는 ‘_’ 도 포함함

RestTemplate

  • 서버-서버 간의 요청을 편리하게 할 수 있는 방법

  • service에서 RestTemplate를 주입해 사용하려고 하면 찾을 수 없다는 문제가 생긴다.

private final RestTemplate restTemplate;
	
	public RestTemplateService(RestTemplate restTemplate) {
	        this.restTemplate = restTemplate;
	    }

RestTemplate는 스프링 부트에서 처음부터 자동 등록되는 것이 아니기 때문이다.

private final RestTemplate restTemplate;

    public RestTemplateService(RestTemplateBuilder builder) {
        this.restTemplate = builder.build();
    }

이처럼 RestTemplateBuilder를 사용해 build 해주어야 한다.

profile
고민고민고민

0개의 댓글