본문 바로가기

기록

웹 백엔드 시스템 구현 스터디(2주차-스프링씨큐러티)

1.

 

@Transactional

 

webmvcConfigure implements WebMvcConfiger?

* 메세지 소스를 셋팅 하기 위해서 어떤 분이 컨피그를 만들었는데 이건 스프링 부트에서

i18n 폴더에 messages.properties 를 생성하여 사용 가능하다.

* MessageSourceAccessor? MessageUtil 을 만들어서 했다.

 

2.

 

리액트 관련 파일을 Static 에 폴더에 넣으면 별다른 설정없이 자동으로 access 가 되는데

다 할필요 없이 특정 리소스 패턴만 mvc 패턴에서 접근 가능하도록 하면 된다. (ResouceHandlerRegistry, addResourceHandler

 

 

 

tip = 컴파일 안잡힐때. 프로젝트 로드 안될때 (java)

1) Project Structure -> Project Sdk 설정,

2) Modules -> src -> mark as 안에 패키지에서 java 누르고 source tap 누르고 resource 누르고 resources tap 누르면 add Content root (아래처럼)

Source Folder ----- src/main/java

Resource Folder ------ src/main/resource (됨)

 

 

3.

 

user Join(가입) 시킬때 JoinRequest 라는 @RequestBody DTO 로 받죠.

SETTER 없고 GETTER 만 있다. JSON 으로 받기위해 (JSON 으로 받으면 객체를 알아서

채워주고 인스턴트화 시켜준다.) 요청에 대한 VALIDATION 은 DTO 안에서

 

##타임라인

  • 00:00:00 1주차 시상식(두구두구)
  • 00:02:55 1주차 미션 리뷰 및 2주차 베이스 코드 설명 - 해리
  • 00:36:15 2주차 베이스 코드 설명 - 잭슨

Model 에서

equals(Object o) , hashCode(), toString() 해도 좋고 안해도 좋지만 toString 은 하는것을 추천한다.

ex)

toString (){

return new ToStingBuilde(this, ).append().append().toString //toStringBuild 찾아보기

}

 

equals 와 hashCode 의 규약을 알고 있어야 한다// 자바의 기초 상식

이쿠얼스는 리턴값 트루이면(동등,동일성 비교) 해쉬코드의 결과값도 반드시 같아야 한다.

ex) user a , user b 일때 a.equals(b) 라면 , a.hashCode() == b.hashCode() 이어야 한다.

하지만 반대는 성립하지 않는다.

도메인 객체? domain, id

 

* space2, Tap, 코드 컨벤션

 

 

[46 : 00] add(<id<Post,Long> postI) 처럼 타입을 줘서 혼란을 막는다.

 

  • 00:49:50 [소소한 팁!] 배너는 손으로 다 찍는다?!

resource 아래 banner.txt 를 넣을수 있다. google text to ASCII Art Generator 에서 생성하고 복사

 

  • 00:52:20 2주차 세션 Agenda
  • 00:53:23 Web 서비스 아키텍처

 

 

아래 내용 한줄 정리 :

REST API 를 만드는 대표적인 3 TIER 아키텍처 패턴, 아 3TIER을 왜쓰냐 어플리케이션 레이어 확장이 가능하기 때문에

SCALE OUT 을 했을때 고려해야할 점은 특정 노드 장애에 대한 고려가 필요하다. (세션 유실)

이걸 어떻게 해결하냐? SESSION CLUSTER 이게 여의치 않으면 JWT 를 사용할수 있고 JWT 를 설명 해 준다.

그다음에는 JWT를 이용한 인증 인가의 과정을 알려줄 예정

Rest APIs are everywhere

3-Tier 아키텍처 (Rest API 를 사용한다는 자체가 3Tier 를 사용한다는 의미이다)

1.프레젠테이션 레이어

2.애플리케이션 레이어 (MVC 패턴)

3. 데이터 레이어

 

3. 3-Tier 아키텍처 수평확장

서버 트래픽이몰린다? 죽고잇다. scale up(cpu, 메모리 추가), scale out (저렴한 장비 추가?)

: 이론적으로 어플리케이션 레이어를 무한적으로 확장 가능

  • 00:59:55 Session 기반 사용자 인증

부정적인 사용자 경험

Sessin 기능을 사용했는데 별다른 고민이 없었다면

1) 문제가 발생한 서버의 모든 사용자 인증 정보를 유실함

2) 즉 해당 서버에서 인증된 사용자들은 다시 로그인 해야함

application server3 이 죽었으면 3에 저장된 세션 아이디 사라짐 다시 2,1 에 접근 했을때

다시 로그인 해야함 -> 부정적 사용자 경험

해결 방법

Session Cluster를 사용한다. 어플리케이션 서버에 저장안하고 세션 클러스터에서 클라이언트 식별한다.

in-memory 분산 데이터베이스 사용한다.

관리포인트 증가와 세션 클러스터의 오류가 걸리면 서비스 전면 장애의 문제가 생긴다.

그래서 보통 서버 여러개로 만들어(그래서 이름이 clustoer) 묶어서 관리한다.

위에건 좀 어려워 ... 세션클래스터링 대신에

stateless 아키텍처와 이 아키텍쳐의 대표 주자 JWT 를 이용한다.

HTTP 근본적으로 무상태(Stateless) 프로토콜이다. statefull 로 바꿔서 사용하는것,

근데 jwt(JSON WEB TOKEN) 를 stateless 를 유지하면서 사용하자는 것이 기본 개념,

사용자 정보가 절대 JWT 에 포함되면 안되고 1, 2 시퀀스나 PRIMARY 키 따위가 담겨야 한다 ,

권한, 토큰 만료 정보,

DECODED 보면 HEADER 는 별로 신경 안쓰고 PAYLOAD 가 정보 SIGNATURE 가 페이로드 부분이 위변조 되지 않았다는 것을 알려주는 정보

 

 

 

11. 페이지 Session 기반 인증 읽어보기

 

 

 

 

  • 01:04:58 Stateless 아키텍처와 JWT(Json Web Token)
  • 01:16:30 Spring Security 기반 인증&인가 처리

 

스프링 시큐리티는 필터의 집합이다.

이 필터들은 중요 필터

SECURITY_CONTEXT_FILTER (인증)

SecutityContextRepository 를 통해 SecurityContext 를 Load/Save 처리

LOGOUT_FILTER (인증)

로그아웃 URL(기본값: /logout)로의 요청을 감시하여 해당 사용자를 로그아웃 시킴

FROM_LOGIN_FILTER (인증)

ID/비밀번호 기반 Form 인증 요청 URL(기본값:/login) 을 감시하여 사용자를 인증함

EXCEPTION_TRANSLATION_FILTER (인증)

요청을 처리하는 중에 발생할 수 있는 예외를 위임하거나 전달

FILTER_SECURITY_INTERCEPTEOR (인가)

접근 권한 확인을 위해 요청을 AccessDecisionManager 로 위임

이 필터가 실행되는 시점에는 사용자가 인증했다고 판단

 

"우리도 jwt 기반으로 필터를 하나 만들어 볼거에요~"

 

Authentication use case

 

 

Spring Security 인증 처리 요약

인증처리를 위한 핵심 컴포넌트

UsernamePasswordAuthenticationFilter (디폴트 인증필터)

사용자 인증요청을 authentication 인터페이스로 추상화하고 authenticationManager 를 호출한다.

Authentication 인터페이스에서 제공하는 핵심 메소드

  • Obect getPrincipal() - 인증아이디
  • Object getCredenticals() - 인증 비밀번호
  • Collection <? extends GrantedAuthority> getAuthorities() - 인증된 사용자의 권한 목록
  • Object getDetail() - 인증된 사용자의 부가정보

AuthenticationManager

  • 사용자 아이디/ 비밀번호를 인증하기 위한 적절한 AuthenticationProvider 찾아 처리를 위임한다.

AuthenticationProvider

  • 실질적으로 사용자 인증을 처리하고, 인증결과를 Authentication 인터페이스로 반환한다.

Spring Security 인증 처리 요약

인가처리를 위한 핵심 컴포넌트

AccessDecitionmanager

AccessDecitionVoter

-- > ppt 30 페이지 확인

 

 

  • 01:30:03 Code와 함께!

JwtAuthenticationTokenFilter.java

http Request-header 에서 JWT 값을 추출하고, JWT 값이 올바르다면 인증정보(JwtAuthenticationToken) 을 생성한다.

생성된( jwtAuthentiactionToken 인스턴스는 SecurityContextHoler 를 통해 Thread-Local(중요) 영역에 저장된다.

인증이 완료된 JwtAuthenticationToken#principal 부분에는 JwtAuthentication 인스턴스가 set 된다.

webSecurityConfiture.java # configure

 

http

.scrf().

disable()

..

// JWT 인증을 사용하므로 무상태(STATELESS) 전략 설정

.sessionCreationPolicy(SessionCreationPolicy.STATELESS)

.and()

.authorizeRequests()

.antMatchers("/api/auth").permitAll()

.antMatchers("/api/user/join").permitAll() // 위 두개 모든 권한

.antMatchers("/api/**").hasRole(Role.USER.name()) // 두개 제외 하고 롤 권한

.anyRequest().permitAll() // 위에 제외하고 모든 권한

..

//// JWT 인증을 사용하므로 Form로긴은 비활성 처리

.formLogin().disable();

 

 

AuthenticProvider 을 원래 구현하는데 jwt 로 custom 구현 예정

1: 50 분부터 다시 보기 

 

process Request - > 아이디와 패스워드를 보내서 인증주체를 의미하는 authentication 을 생성한다 

그리고 authentication 을 authenticationManager 에 위임을 한다. 

provider list 에서 원하는 provider 선택 ,, 

샬라샬라 해서 로그인철. 

그리고 userService 로 로그인하고 인증주체를 생성한다.

근데 만드는데.. authenticationToken 에 Object 에 principal 

 

accessDecision 매니저,, 

JwtauthenticationTokenFilter.java

new JwtAuthenticationToken(new JwtAuthentiction(userKey, email), null, authorities);

authentication.setDetail(new WebAuthentictioDetailsSource().buildDetails(request))

 

 

jwt 토큰을 가져와서 이게 올바를 jwt 토큰이라면 토큰을 디버그 하고(payload, Jwt.claims)

를 가지고 와서 컨트롤러에 넣는다. 

(@AuthenticationPrincipal JwtAuthentication authentication) 

AuthenticationPrincipal 은 JwtAuthenticationToken 에서

Object principal 을 꺼내오는 부분이다.

 

(AuthenticationManager 는 인터페이스 구현해야함) 

  • 02:00:30 2주차 미션 소개

JWT 적용을 위한 Spring Security 커스터 마이징

Spring Security 커스터마이징을 위한 핵심 컴포넌트 분석 

UsernamePasswordAuthenticationFilter 

- HTTP 요청에서 사용자 ID, 비밀번호 추출

- UsernamePasswordAuthenticationToken 을 생성해, AuthenticationManager를 호출

 

UsernamePasswordAuthenticationToken 

- 사용자 인증 요청을 추상화한 Authentication 인터페이스 구현체 

- principal 멤버 변수는 2개의 의미로 사용

- 인증전 : 사용자 ID / 인증 후 : 사용자 도메인 모델 

 

DaoAuthenticationProvider 

- UserDetailService 를 통해 사용자 정보를 데이터베이스에서 조회 

- 실직적인 사용자 인증처리 로직을 수행함 

- 인증 결과는 UsernamePasswordAuthenticationToken 타입으로 반환

 

voter?!?!?!?!?! cannectionbasedVoter

 

##질문 답변 빠르게 보기 👀

  • 00:22:25 queryForObject에 대해
  • 00:25:21 VO와 DTO?
  • 00:27:34 패스워드 수정 필요 시 DTO 구성
  • 00:28:25 Email은 DTO?
  • 00:30:47 Mock와 MockBean의 차이점

 

  • 00:31:27 토비의 스프링 외 참고하면 좋을 것들 추천!

- 스프링 MVC 보다는 어떻게 ENTITY, DTO 와 도메인, 서비스 작성,, 도메인 관련책 많이 읽으세요?

책 외에도 많은 코드를 보는게 좋을것 같아요.

  • 00:33:32 DTO의 위치는 어디에 두는 것이 좋을까요?

- Package구조 관련 Article 아는거 하나있는데 전달 해드릴게요~

 

 

Spring Security

Spring Security 처리흐름에 대한 전반적인 설명

Spring Security를 최대한 쉽게(?) 설명한 글 모음

Spring Security 인가 처리 설명

Spring Security Test

HTTP 세션

HTTP 세션 개요

Redis를 활용한 Spring Boot 세션 클러스터 예제

JWT

JWT 소개

Java-Jwt 라이브러리

Spring-Boot, Security로 구현하는 Jwt

Jwt 콘솔 (Jwt 디코드 및 검증)

 

 

 

반응형