Spring

Spring Security 기본(세션, 스프링시큐리티)

code2772 2023. 3. 13. 13:29
728x90
반응형
스프링 시큐리티란
- 인증/인가와 보안 기능을 담당하는 라이브러리
- 쉽게 풀이하면 로그인, 권한설정, 권한검사 기능 등을 제공
- 원리 : 서블릿 필터를 이용
   사용자가 리퀘스트를 주면 스프링 엠브시에서 리스폰스를 줌

즉 사용자가 리퀘스트를 서블릿 컨네이너에 주고 서블릿 컨네이너 즉 톰켓과 같은 것이 리스폰스해준다.
다시 서블릿 컨네이너에서 스프링 DispatcherServlet 에 요청하면 컨네이터네 리스폰스 해준다.

서블릿 컨네이너에서 리스폰스 리퀘스트간 스프링 디스패치 사이에 필터로 시큐리티를 구현

바로 필터를 구현하면 스프링 빈을 인식하지 못하므로, 스프링에게 구현을 위임한다.

스프링 시큐리티 bean은 필터들로 구성되어 있고, 이 필터들의 모음을 securityfilterchain이라고 부른다.
필터는 각각 고유한 역할을 담당하며 default로 등록되는 필터는 존재한다.
예) AbstractAuthenticationProcessiongFilter는 인증을 담당

자동으로 비밀번호가 생성되는것을 확인할 수 있으며 새로 시작하는 경우 비밀번호는 계속 변동된다.

회원가입/로그인 구현
구현방법은 다양하나 핵심은 스프링시큐리티 인터페이스를 사용
- 스프링시큐리티 흐름을 이해하고 인터페이스를 사용
- 모든 흐름을 커스터마이징할 것인다, 일부 흐름만 커스터마이징할 것인가는 개발자 선택

프로젝트 생성
- /login, /logout API가 자동으로 생성
- 로그인 : /login(post)
   계정 : user, 비밀번호 : 프로젝트 실행 후 확인한 비밀번호
- 로그아웃 : /logout(post) 기존 패스워드는 계속 다르다.

인증필터 디버깅
- 로그인을 요청하면 breakpoint에 멈췄으므로 usernamepasswordauthenticationfilter가
 로그인(인증)을 담당하는 것을 확인할 수 있다.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {
    @GetMapping("/")
    public String helloworld() {
        return "hello world";
    }

스프링 시큐리티를 사용하면 따로 html 파일을 만들지 않아도 위와 같은 화면이 나온다.

로그인하면 나오는 화면

 

세션 - 서블릿 컨네이너 자체가 세션을 발급을(ID에) 해준다.
- 로그인 여부 등 HTTP 통신에 필요한 데이터를 서버 메모리에 저장하는 방법
    * 서버가 재부팅되면 기존에 저장된 데이터는 사라진다.
- springsecurity는 기본으로 세션으로 로그인 여부를 관리
    예) default설정 : 세션이 없으면 로그인이 안되었다는 것으로 간주하여 로그인페이지로 리다이렉트
- 로그인이 성공하면 새로운 세션 발급

스프링 시큐리티 단점 - 동시 로그인이 가능하다. 세션 하이제킹

백엔드 프론트 연동
- 프론트는 백엔드 API호출할 때 세션을 같이 넘겨야 한다.
- 스프링시큐리티는 프론트가 전송한 세션을 사용해서 인증을 검사한다.
- 백앤드 개발자는 세션인증 로직을 개발하지 않아도 된다.
    frontend -> jessionid -> backend

로그인된 유저 조회
- 스프링시큐리티는 spring mvc에서 로그인된 유저를 가져올 수 있도록 어노테이션 제공
    @AuthenticationPrincipal : 로그인 객체를 받아오고 유저 정보를 얻을 수 있다.

✔ 컨트롤러 부분

@GetMapping("/session")
public ResponseCookieDto hello(@AuthenticationPrincipal User user, HttpSession HttpSession) {
    String username = "empty";
    String session_id = "empty";

    if (user == null) {
        System.out.println("user is empty");
    }else{
        session_id = HttpSession.getId();
        username = user.getUsername();
    }
    return new ResponseCookieDto(username, session_id);
}

✔ DTO 부분

package com.demo.springSecurity.controller;

public class ResponseCookieDto {
    public String username;
    public String session_id;

    public ResponseCookieDto(String username, String session_id){
        this.username=  username;
        this.session_id=  session_id;
    }

}

반응형