Authentication // Authorization

 

Spring에서는 대표적으로 Spring Security를 적용하여 인증 / 인가를 관리한다.

 

<Authentication>

유저가 해당 유저가 맞는지 (지문인식, ID/PW비교, Face ID   등)

 

<Authorization>

유저가 해당 리소스에 접근 가능한지 (접근권한)

eg) 관리자 페이지, 회원페이지, 관리자 권한 ... etc

 

 

<Web Application에서의 Authentication>

HTTP 통신은 비연결성, 무상태의 특징을 가짐

Web App에서는 일반적으로 서버-클라이언트가 항시 연결되어있는 것이 아님 (비연결성 - Connectionless)

서버가 클라이언트의 상태를 저장하지 않는다. (무상태 - Stateless)

 

그런데 우리가 웹서핑을 할때, News/Sports/9 에서 뒤로가기를 누르면 이전 정보가 불러와지는것처럼 보임

계층적인 URL  설계를 통해 다음 요청 URl을 이전 계층에 두었기 때문.

그럼 요청이 갈 때마다 인증을 다시하는가 ? NO. 무상태 프로토콜에서 인증을 유지시키는 방법 

1. 쿠키-세션 방식

 - 클라이언트의 쿠키와 서버의 세션에 사용자 key를 저장하고, 요청에 쿠키를 담아 서버에서 검증

쿠키

2. JWT(JSON web token) 방식

- JSON 포맷을 이용하여 사용자 속성을 저장하는 Claim 기반의 웹 토큰

- 로그인 요청이 확인되면, JWT를 발급하여 클라이언트에게 보냄. 클라이언트는 토큰을 저장소에 보관하고, 요청마다 토큰을 같이 보냄. 서버에서는 토큰을 검증

- 세션 유지의 경우, 서버가 여러개일 경우 세션 Storage를 따로 구축해야함. JWT는 Secret Key만 공유하면 위조검증 가능

     ==> 동시접속자가 많을 때 서버측 부하를 낮출 수 있다

     ==> Client, Server가 다른 도메인을 사용 할 때 쉽다(OAuth같은 경우)

- 단점 :  구현의 복잡도가 증가하고, JWT에 담는 내용이 커질수록 네트워크 비용 증가 (클라이언트 -> 서버)

             기존 생성된 JWT를 일부만 만료시킬 방법이 없다.

              Secret Key 유출시 JWT 조작 가능

 

각 방법을 고도화 한 방법이 있고, OAUTH 소셜로그인도 있다.

 

<JWT>

https://jwt.io/introduction

JWT 토큰은 HMAC 알고리즘으로 secret_key에 의해 sign 되거나,

                    RSA / ECDSA를 사용하여 public, private key에 의해 서명된다.

 

Secret_key로 구현해보자

 

<구현>

@PostConstruct : 의존성이 주입되고 나서 실행됨을 보장하는 annotation.

JWS가 만들어지는 과정 대충

subject 인코딩 -> 암호화 알고리즘 -> secret key로 서명

claim 인코딩 -> 암호화알고리즘 -> secret key로 서명

필요한 부분들을 인코딩하고 secret key와 암호화알고리즘으로 서명하고, .으로 구분해 3 부분의 문자열로 만듬.

 

코드를 보면

1Jwts.builder 활용.

2.Subject 추가(여기선 유저이름)

3.claim추가("Key", value) => 토큰이 디코딩 시 제공해야하는 정보를 담음(권한같은거)

4.발행시간, 만료시간 추가

5.암호화된 key와 signature 알고리즘 명시

6.변환한 뒤, compact()로 압축

==> asfklsafakljsfhaksldjfhd.jasdiflasdjflidsafj.asldfjksdakldsjalk   와 같은 JWS 발급

 

//////////////Decoding///////////////

Claims 객체를 반환하며, claim.getBody().getSubject()와 같이 claim들을 가져올 수 있다.

+ Recent posts