국비학원 48일차 : Spring Boot_8

Digeut·2023년 5월 3일
0

국비학원

목록 보기
40/44

Security

인증

사용자의 신원을 확인하는 과정으로, 사용자가 시스템에 액세스하려고 할 때, 사용자가 자신이 주장하는 사람임을 증명해야 한다. 신원을 확인하는 방법으로는 이름-비밀번호, 토큰, 생체 인식, 전자 서명 방식으로 인증을 수행할 수 있다. 사용자가 누구인지 확인하는 것이다.

인증 실패 : 401

인가

인증된 사용자에게 특정 자원이나 기능에 대한 권한을 부여하는 과정이다. 사용자가 시스템에서 수행할 수 있는 작업을 제한하고, 보안 수준을 높이는 데 도움이 된다. 이미 누구인지 인증을 통해 알고 있는 사용자에게 우리가 제공할 서비스를 이용할 권한이 있는지 확인하는 것이다.

인가 실패 : 403

접근주체

시스템이나 애플리케이션에서 인증 및 인가 과정을 거치는 개체를 의미한다. 일반적으로 사용자, 그룹, 서비스 또는 애플리케이션 등을 포함할 수 있다. 접근 주체는 자신의 인증 정보(이름-비밀번호, 토큰, api key 등)를 사용하여 인증을 받게 된다.

인증방식

Basic Authentication

웹에서 가장 간단한 형태의 인증 방법 중 하나이다. 클라이언트와 서버 간에 사용자 이름과 비밀번호를 통해 인증을 수행한다. 특정 리소스에 접근하기 전에 사용자의 신원을 확인하는데 사용된다. 일반적으로 아이디와 비밀번호를 이용해 로그인하는 방식이다.

Basic Authentication 인증 단점

  • 보안성: base64 인코딩은 실제로 데이터를 암호화하지 않기 때문에, 네트워크 상에서 데이터가 가로채지기 쉽다. 따라서 HTTPS와 같은 보안 프로토콜과 함께 사용하는 것이 좋다.
  • 사용자 경험: 브라우저가 제공하는 기본 인증 창을 사용해야 하므로, 사용자 경험을 개선할 수 있는 여지가 없다.
  • 로그아웃 기능 부재: HTTP Basic Authentication은 상태를 유지하지 않기 때문에, 로그아웃 기능을 구현하기가 어렵다.

Bearer Token Authentication

클라이언트와 서버 간 인증을 위해 사용되는 방식 중 하나로, Bearer Token을 이용해 인증 정보를 전달한다. Bearer Token은 일반적으로 클라이언트에게 서버로부터 발급된 고유한 문자열로, 이를 통해 클라이언트가 서버에 인증되어 리소스에 접근할 수 있다. 상대방이 이름 혹은 특정한 문자를 보내면 그 결과에 맞는 문자열을 반환해준다. 이를 통해서 다음 요청을 보낼때마다 토큰을 포함해서 보내게 된다.

주로 사용하게되는 토큰. 여기서 사용되는 토큰이 JWT


빨간색이 Header, 분홍색이 Payload(Claim이라고도 함), 하늘색이 Verify Signature
payLoad부분에 만료기간이 표시되게 된다.

Bearer Token Authentication 인증 과정

  • 클라이언트는 사용자 이름과 비밀번호 또는 다른 인증 방식을 사용하여 토큰 발급 서버로부터 Bearer Token을 받는다.
  • 클라이언트는 이후의 모든 요청에서 발급받은 Bearer Token을 'Authorization' 헤더에 포함시켜 전달한다. Authorization: Bearer {token}과 같은 형식으로 헤더에 포함시킨다.
  • 서버는 'Authorization' 헤더에 포함된 Bearer Token을 검증하여 유효한 토큰인 경우, 클라이언트에게 해당 리소스에 대한 접근 권한을 부여한다.


Bearer Token Authentication 인증 장점

  • 상태를 유지하지 않는 인증: 서버는 각 요청에 대한 인증 정보를 토큰에서 직접 가져올 수 있으므로, 별도의 세션 저장소가 필요하지 않다. 토큰의 유효기간을 설정해서 사용할 수 있다.
  • 확장성: 서버는 토큰 발급, 인증, 리소스 제공 등의 역할을 분리하여 구현할 수 있으므로, 확장성이 높다.
  • 보안성: 토큰은 일반적으로 암호화되어 있기 때문에, 데이터의 무결성과 기밀성을 보장할 수 있다.

Bearer Token Authentication 인증 주의 사항

토큰이 탈취되면 악용될 수 있는 문제가 있다. 따라서 HTTPS와 같은 보안 프로토콜과 함께 사용하여 토큰이 네트워크 상에서 가로채지 않도록 하는 것이 중요하다. 또한 토큰의 유효 기간을 제한하거나, 클라이언트 IP와 연관된 정보를 토큰에 포함시켜 추가적인 보안 조치를 취할 수도 있다.

JWT

Header (헤더) : 토큰의 유형 (일반적으로 "JWT")과 서명에 사용되는 알고리즘 (예: HMAC SHA256 또는 RSA)이 포함됩니다. 암호화된 데이터를 해독하는 방법을 설명하며, 토큰의 유형 및 사용되는 해시 알고리즘 등의 정보를 포함합니다.

Payload (페이로드) : 클레임이라고도 불리는 페이로드에는 전달할 정보가 들어 있습니다. 이 정보는 일반적으로 사용자 정보, 권한 등을 나타내는 속성입니다. 클레임은 등록된 클레임, 공개 클레임, 비공개 클레임 세 가지 유형이 있습니다. 토큰에 저장되는 클레임 정보를 포함합니다. 클레임 정보는 사용자 ID, 권한 등과 같은 데이터를 포함할 수 있습니다. 보안 및 무결성에 '주의'해야 하며, 각 요청에 대한 처리 비용이 발생할 수 있습니다. SignitureKey를 복잡하게 사용하고, 만료기한을 꼭 지켜줘야한다. (일반적으로 1시간으로 한다) 또다른 보안처리로 payload 자리에 민감함 정보를 넣으면 안됩니다. 민감하진 않고 자주사용해야되는 데이터를 넣어줘야합니다.

Signature (서명) : 헤더와 페이로드를 인코딩하고, 비밀 키를 사용하여 서명하여 생성됩니다. 이 서명은 토큰의 무결성을 보장하고 변조를 방지합니다. 서버에서 생성한 서명 키를 사용하여 헤더와 페이로드를 인코딩한 후에 생성됩니다. 서명은 토큰이 변조되지 않았는지 검증하는 데 사용됩니다. 사용가능한 토큰인지 불가능한 토큰인지를 나타내는것 시그니처키를 포함시킵니다. 어떤 키를 사용해서 서명했는지 담아주는데 그건 나타나지않습니다. 발급당시 사용한 서명키와 여기서 사용한 서명키가 다르면 VERIFY가 되지 않습니다.

JWT는 인증된 사용자에 대한 정보를 포함하고 있으므로, 사용자가 자신의 정보를 요청할 때마다 인증서버에 요청하지 않고도 필요한 정보를 효율적으로 전달할 수 있습니다. 이를 통해 서버의 부하를 줄이고 응답 시간을 단축시킬 수 있습니다.

JWT는 비교적 간단하고 가볍기 때문에 인증 정보를 안전하게 전송하는 데 유용합니다. 하지만, 보안적인 이슈가 발생할 수 있으므로 서버와 클라이언트 간의 통신을 안전하게 보호하는 다른 추가적인 보안 기술과 함께 사용해야 합니다. JWT는 토큰 생성 후, 전송되는 동안 또는 서버에서 저장될 때 일반적으로 Base64Url로 인코딩됩니다. 인코딩된 헤더, 페이로드, 서명은 각각 점(.)으로 구분되어 하나의 문자열로 연결됩니다.

Spring Boot에서 사용

jjwt 의존성 주입

build.gradle

implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'

provider - JwtTokenProvider

@Component //component로 등록, Autowired 통해서 IOC가능.
public class JwtTokenProvider {
    
    //jwt 생성 혹은 검증에 사용될 시크릿 키
    //시크릿 키 같은 데이터는 보안에 유의해야 하기때문에
    //application.propertise 또는 시스템 환경변수로 등록해서 사용함.
    //jwt하려면 secret-key가 필요함.
    @Value("${jwt.secret-key}") //application.propertise에 적은것 불러옴.
    private String SECRET_KEY ;

    //JWT 생성 메서드
    public String create(String subject){
        //만료시간
        Date expiredDate = Date.from(Instant.now().plus(1,ChronoUnit.HOURS));
        //생성
        String jwt = Jwts.builder()
            .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
            .setSubject(subject)
            .setIssuedAt(new Date())
            .setExpiration(expiredDate).compact();
        return jwt;    
    }

    //JWT 검증, 생성된 jwt를 받아서 parser을 하고 claim(payroad)으로 바꿔준다
    public String validate(String jwt){
        Claims claims = 
            Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(jwt)
                .getBody();
        return claims.getSubject();
    }
}

application.propertise

jwt.secret-key=Secret1!

일반적으로 application.propertise은 깃에 등록하지 않는다. 보안적 문제. 일반적 코드로 등록을 하면 scretKey까지 드러나기때문에 다른 곳에서 보안적인 측면으로 작성한다.

@Value("${jwt.secret-key}")

Spring Framework에서 제공하는 어노테이션 중 하나로, application.properties나 application.yml 파일에 설정된 속성 값을 가져오는 기능을 합니다.

${jwt.secret-key}는 application.properties 파일에 정의된 jwt.secret-key 속성 값이 들어갑니다. 따라서 이 코드는 jwt.secret-key 속성 값을 가져와서 해당 변수에 할당합니다.

JWT 토큰을 생성하고 검증할 때는 서명을 생성하고 검증하는 데 사용되는 비밀키(secret key)가 필요합니다. 이 때 jwt.secret-key 속성 값은 JWT 서명에 사용될 비밀키를 설정하는 데 사용됩니다. 이렇게 속성 값을 외부 설정 파일에 저장하여 사용하면, 코드 내에서 직접 비밀키를 하드코딩하는 것보다 안전성과 유지보수성이 좋아집니다.

따라서 @Value("${jwt.secret-key}")는 외부 설정 파일에서 jwt.secret-key 속성 값을 가져와 해당 변수에 할당하는 기능을 합니다. 이를 통해 JWT 서명에 사용될 비밀키를 안전하게 관리할 수 있습니다.

JwtTokenProvider 파일은 Spring Security 프레임워크에서 JWT(JSON Web Token) 인증을 처리하기 위한 클래스입니다. JWT를 생성하고 검증하기 위한 여러 메서드를 제공합니다. 주요 기능은 다음과 같습니다.

JWT 생성: 사용자 정보와 만료 시간 등을 기반으로 JWT 토큰을 생성합니다.
JWT 파싱: JWT 토큰에서 사용자 정보와 만료 시간 등의 정보를 추출합니다.
JWT 유효성 검증: JWT 토큰이 유효한지 확인합니다. 이를 위해 서명을 검증하고 만료 시간 등의 정보를 확인합니다.

파싱

파싱(Parsing)은 컴퓨터 프로그램에서 텍스트 형식으로 작성된 데이터를 읽어들여서 컴퓨터가 이해할 수 있는 구조로 변환하는 과정.

JWT(JSON Web Token)에서도 파싱이 필요합니다. JWT는 Base64 인코딩된 문자열 형태로 되어 있으며, 이 문자열에서 Header, Payload, Signature 등으로 나누어진 정보를 추출해야 합니다. 이를 위해 JWT 파서(JWT Parser)를 이용하여 JWT 문자열을 파싱하여 각각의 정보를 추출할 수 있습니다.

따라서 파싱은 텍스트 형식으로 작성된 데이터를 컴퓨터가 이해할 수 있는 구조로 변환하는 과정을 말하며, JWT에서는 JWT 문자열을 파싱하여 각각의 정보를 추출하는 과정을 의미합니다.

service - MainService

public interface MainService {
    public String hello();
    public String getJwt(String data); //jwt가져오기
    public String validJwt(String jwt); //jwt검증
}

service - implement - MainServiceImplement


@Component 
//지정해둔 클래스에만 Ioc 시킬수 있고 autowierd로 가져올수 있게 된다 
//@service 해도 이름을 지정해준거지 컴포넌트의 역할을 한다
public class MainServeceImplement implements MainService {

    private JwtTokenProvider jwtTokenProvider;

    @Autowired //의존성 주입
    public MainServeceImplement(JwtTokenProvider jwtTokenProvider){
        this.jwtTokenProvider = jwtTokenProvider;
    }

    @Override
    public String hello() {
        return "Hello";
    }
    //메인 서비스 구현하도록 해줌

    @Override
    public String getJwt(String data) {
        String jwt = jwtTokenProvider.create(data);
        return jwt;
    }

    @Override
    public String validJwt(String jwt) { //검증
        String subject = jwtTokenProvider.validate(jwt);
        return subject;
    }
}

controller - MainController

@RestController
public class MainController {
    
    private final MainService mainService;

    @Autowired //IOC를 적용할수 있다.
    public MainController(MainService mainService){
        this.mainService = mainService;
    }

    @GetMapping("/hello")
    public String hello(){
        return mainService.hello();
    }

    @GetMapping("/jwt/{data}")
    public String getJwt(
        @PathVariable("data") String data
        ){
        return mainService.getJwt(data);
    }

    @PostMapping("/jwt")
    public String validJwt(
        @RequestBody String jwt
    ){
        return mainService.validJwt(jwt);
    }
}

Spring Security

Spring Security는 Spring Framework 기반의 보안 프레임워크로, 웹 어플리케이션에서 인증(Authentication)과 권한 부여(Authorization)를 관리하기 위한 기능을 제공합니다.

인증 (Authentication): Spring Security는 다양한 인증 방법을 지원하며, 사용자 정의 인증 메커니즘이나 외부 인증 제공자와 함께 작동할 수 있다. 예를 들어, 폼 기반 인증, HTTP 기본 인증, OAuth2, LDAP, SSO 등을 지원한다.

인가 (Authorization): Spring Security는 접근 제어 목록 (ACL) 및 역할 기반 접근 제어 (RBAC)를 통해 자원에 대한 권한을 관리한다. 이를 통해 개발자는 URL 패턴, 메서드 수준의 보안(사용자는 get, post메서드만 쓸수 있다 이런 단계의 보안), 객체 인스턴스 수준의 보안 등을 적용할 수 있다.

세션 관리: Spring Security는 웹 애플리케이션에서 세션 관리를 도와준다. 이를 통해 개발자는 세션 고정 공격에 대한 보호, 동시 세션 제한, 세션 만료 등을 처리할 수 있다.

CSRF(Cross-Site Request Forgery) 방어: Spring Security는 CSRF 공격에 대한 기본적인 방어 메커니즘을 제공한다. 이를 통해 웹 애플리케이션에서 사용자의 요청에 대한 보안을 강화할 수 있다.

확장성: Spring Security는 확장성이 높은 구조를 가지고 있어, 개발자가 커스텀 보안 요구 사항을 쉽게 구현할 수 있다.

통합: Spring Security는 다른 Spring 프로젝트 및 오픈 소스 프로젝트와 잘 통합되어 있다. 예를 들어, Spring Boot, Spring Data, Spring Cloud, Thymeleaf 등과 함께 사용할 수 있다.

CSRF

CSRF(Cross-site Request Forgery)는 웹 어플리케이션 취약점 중 하나로, 인증된 사용자가 의도하지 않은 요청을 보내는 공격을 의미합니다.

일반적인 웹 어플리케이션에서는 사용자가 로그인을 하고 인증 토큰을 발급받아 인증된 요청을 보내게 됩니다. 하지만 CSRF 공격을 통해 공격자는 인증된 사용자의 브라우저를 이용하여 '인증 토큰을 취득'하고, 이를 이용하여 사용자가 모르는 사이에 원치 않는 요청을 보낼 수 있습니다.

예를 들어, 사용자가 은행 웹 사이트에 로그인하여 계좌 이체를 수행하려고 할 때, 공격자가 링크를 클릭하게끔 유도하여 은행 계좌 이체를 요청하도록 만들면, 공격자가 은행 계좌를 조작할 수 있게 됩니다.

CSRF 공격을 방지하기 위해서는, 사용자의 인증 정보와 함께 인증 토큰을 생성하고, 이를 모든 요청에 포함하여 보내야 합니다. 이를 CSRF 토큰(CSRF Token)이라고 합니다. 서버는 요청을 처리할 때, 이 CSRF 토큰을 검증하여 해당 요청이 유효한 것인지 확인합니다.

Spring Security에서는 CSRF 공격을 방지하기 위해 CSRF 토큰 기능을 제공하며, 기본적으로 활성화되어 있습니다. 따라서 Spring Security를 사용할 때는 CSRF 공격에 대한 대비책을 반드시 마련하여야 합니다.

Spring Security 의존성 추가

build.gradle

implementation 'org.springframework.boot:spring-boot-starter-security'

filter - JwtAuthenticationFilter

@Component
public class JwtAuthenticationFilter extends ⭐OncePerRequestFilter {

OncePerRequestFilter

Filter 인터페이스를 구현한 클래스입니다. 이 클래스는 Spring Security 필터 체인에서 단 한번만 호출되도록 보장해줍니다. 따라서 동일한 요청에 대해 여러 번 필터가 실행되는 것을 방지하고, 불필요한 작업을 줄일 수 있습니다.

예를 들어, 사용자 인증 정보를 검사하는 필터를 만들 경우, OncePerRequestFilter를 상속받아서 해당 필터를 구현하면 됩니다. 이 필터는 🌼doFilterInternal 메소드를 구현하여 요청에 대한 처리를 수행합니다.

OncePerRequestFilter를 사용하면, Spring Security 필터 체인에서 해당 필터가 한번만 실행되므로, 동일한 요청에 대해서 중복적인 작업을 방지할 수 있습니다. 또한 필터 체인 내에서 여러 번 호출될 가능성이 있는 경우에는, 성능 이슈를 예방할 수 있습니다.

    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    public JwtAuthenticationFilter(JwtTokenProvider jwtTokenProvider){
        this.jwtTokenProvider  = jwtTokenProvider;
    }

    @Override
    protected void 🌼doFilterInternal(HttpServletRequest request, 
    			HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
       try {

        String jwt =parseToken(request); //parsing
		
        //유효성 검사
        //JWT가 없거나, "null"과 같다면 필터 체인을 계속 진행하고 메소드를 종료한다.
        boolean hasJwt = jwt != null;
        if(!hasJwt) {
            filterChain.doFilter(request, response);
            return;
        }
        
		//JWT가 유효하다면, 토큰 제공자를 사용하여 JWT의 subject를 검증한다.
        String subject = jwtTokenProvider.validate(jwt); //subject 꺼내올수있다.

		//🌷UsernamePasswordAuthenticationToken 객체는 
        //사용자의 이름, 비밀번호 및 권한 목록을 포함할 수 있다. 
        //여기서는 사용자 이름(subject)만 사용하고, 
        //비밀번호와 권한 목록은 사용하지 않는다.
        AbstractAuthenticationToken authenticationToken = 
            new 🌷UsernamePasswordAuthenticationToken(subject, null, 
            							AuthorityUtils.NO_AUTHORITIES);
        
        //인증 요청에 대한 세부 정보를 설정한다. 
        //여기에서는 웹 인증 세부 정보 소스를 사용하여 요청에서 세부 정보를 구축합니다.                               
        authenticationToken.setDetails(
        				new WebAuthenticationDetailsSource()
                        .buildDetails(request));
		
        //🍉빈 보안 컨텍스트를 생성하고, 
        //생성한 UsernamePasswordAuthenticationToken 객체로 인증 정보를 설정한다.
        SecurityContext securityContext = 
        			SecurityContextHolder.🍉createEmptyContext();
        securityContext.setAuthentication(authenticationToken);
		
        //최종적으로, 설정된 보안 컨텍스트를 
        //현재 스레드의 SecurityContextHolder에 설정한다. 
        //이렇게 하면 이후 처리 단계에서 인증 정보를 사용할 수 있다.
        SecurityContextHolder.setContext(securityContext);

       } catch (Exception exception) {
            exception.printStackTrace();
       }

       filterChain.doFilter(request, response); 
       //이렇게 해야 다음 필터로 넘어갈수 있다. 필터 벗어나기
    }

    //Parsing 진행
    private String parseToken(HttpServletRequest request){

        //Request Header 중 "Authorization" : "Bearer eyJhbGci..."값 가져온다
        String  token = request.getHeader("Authorization");

        boolean hasToken = 
                token != null && 
                !token.equalsIgnoreCase("null");
        if(!hasToken) return null;

        //"Bearer eyJhbGci..." 인지 확인하는 것
        boolean isBearer = token.startsWith("Bearer ");
        if(!isBearer) return null;

        //"Bearer eyJhbGci..." 인덱스 7번부터 값을 가져오겠다. 
        //앞의 7번째 인덱스까지는 제거하고 실제 토큰을 가져온다
        String jwt = token.substring(7);
        return jwt;
    }
    
}

config - WebSecurityConfig

@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
    
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Autowired //JwtAuthenticationFilter의 인스턴스를 주입한다.
    public WebSecurityConfig(
        JwtAuthenticationFilter jwtAuthenticationFilter
    ){
        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
    }

    @Bean //SecurityFilterChain 빈을 생성하고 구성한다. 
    //이 메소드에서는 HttpSecurity를 사용하여 웹 애플리케이션의 보안 설정을 정의한다.
    protected SecurityFilterChain configure(HttpSecurity httpSecurity) 
    								throws Exception{ //모든 예외를 호출부로
		
        //CORS(Cross-Origin Resource Sharing)를 활성화하고,
        //CSRF(Cross-Site Request Forgery) 및 기본 인증을 🍭비활성화합니다.
        httpSecurity.cors().and()
                    .csrf().disable()🍭
                    .httpBasic().disable()🍭
					// 세션 관리 전략을 설정한다. 
                    //여기서는 세션 생성 정책을 🧃STATELESS로 설정하여
                    //서버가 세션을 생성하지 않도록 한다.
 					.sessionManagement().sessionCreationPolicy(
                    		SessionCreationPolicy.🧃STATELESS).and()
					//🥕접근 권한을 설정한다. 
                    //여기에서는 "/", "/api/auth/**"와 같은 경로에 대한 요청은 
                    //모두 허용하며, 나머지 요청은 인증된 사용자만
                    //접근할 수 있도록 설정한다.
                    .🥕authorizeRequests().antMatchers("/jwt/**").permitAll()
                    .anyRequest().authenticated();
		//JwtAuthenticationFilter를 HttpSecurity 필터에 추가한다. 
        //이 필터는 요청이 들어올 때마다 JWT 인증을 처리한다.
        httpSecurity.addFilterBefore( //실행되는 필터 위치 지정해준것
        					jwtAuthenticationFilter, 
                            UsernamePasswordAuthenticationFilter.class);
        //최종적으로 구성된 HttpSecurity 객체를 빌드하여
        //SecurityFilterChain 객체를 반환다.		
        return httpSecurity.build();
    }
}

@EnableWebSecurity

Spring Security의 웹 보안 기능을 활성화할 수 있습니다.
@EnableWebSecurity 애노테이션은 WebSecurityConfigurerAdapter를 상속받는 클래스에서 사용됩니다. WebSecurityConfigurerAdapter는 Spring Security의 웹 보안 설정을 구성하는 클래스로, @EnableWebSecurity 애노테이션이 선언된 클래스에서 WebSecurityConfigurerAdapter를 상속받아서 보안 설정을 구성합니다.

@Configuration

@Configuration 애노테이션을 사용하여 Spring Framework에게 해당 클래스가 Bean Configuration을 포함한다는 것을 알리고, @Bean 애노테이션을 사용하여 메소드가 반환하는 객체가 빈(Bean) 객체임을 명시합니다.

@Bean

해당 메소드가 Spring 컨테이너에서 관리하는 빈(Bean) 객체를 반환함을 나타냅니다. ApplicationContext에 등록된 빈(Bean) 객체를 정의할 수 있습니다. 즉, @Bean이 붙은 메소드는 Spring 컨테이너가 실행할 수 있는 메소드로, 해당 메소드가 반환하는 객체를 Spring 컨테이너가 관리하는 빈(Bean) 객체로 등록합니다.

controller - RestApiController

@GetMapping("get-method")
    public String getMethod(
        ✔️@AuthenticationPrincipal String 💡subject
    ){
        //return  restApiService.getMethod(); //"Response of Get Request";
        return subject;
       
    }

UsernamePasswordAuthenticationToken에 사용한 name인 subject를 사용할수 있게 된다.

filter - JwtAuthenticationFilter

AbstractAuthenticationToken authenticationToken = 
            new UsernamePasswordAuthenticationToken(💡subject, null, 
            							AuthorityUtils.NO_AUTHORITIES);

PasswordEncoder

비밀번호를 안전하게 저장하고 검증하기 위한 인터페이스이다. 사용자 비밀번호를 평문으로 저장하는 것은 보안상 취약하므로, 대신 비밀번호를 해시하고 솔트를 추가하여 저장하는 것이 좋다. 솔트는 해시 충돌을 줄이고, 무차별 대입 공격(brute-force attack)에 대한 저항성을 높여준다.

  • String encode(CharSequence rawPassword): 평문 비밀번호를 인코딩(해시)하여 반환한다. 일반적으로 해시와 솔트를 포함한 결과를 반환한다.

  • boolean matches(CharSequence rawPassword, String encodedPassword): 평문 비밀번호와 인코딩된 비밀번호가 일치하는지 확인한다. 인코딩 과정을 거친 후, 결과가 저장된 인코딩된 비밀번호와 동일한지 확인하여 검증한다.

profile
개발자가 될 거야!

0개의 댓글