티스토리 뷰

Auth & HTTPS

Authorization & Authentication

Auth: 로그인 과정에서 일어나는 일들을 함축하는 단어. Authorization & Authentication

  • 사용자가 자신이 누구인지를 증명하는 과정 -> Authentication (로그인, 소셜 로그인)
    • API서버를 사용할 때에도 API ID키를 발급받고 그것을 서비스 제공자가 원하는 형태로 가공해서 전달함으로써 사용하기도 함. 이것도 Authentication과정으로 볼 수 있음
  • 사용자의 기능 사용 권한을 검증하는 과정 -> Authorization (권한 관리, 작성, 차단 등)

Authentication

브라우저에는 브라우저가 가지고 있어야 할 정보가 쿠키 형태로 저장됨

쿠키는 브라우저가 설정하기도 하고, 요청을 보내는 서버에서 전송해주기도 함

사용자가 클라이언트 브라우저 쪽에서 로그인을 요청함

로그인을 요청할 때 아이디, 비밀번호 등의 내용이 포함됨

옳은 정보일 경우, 서버에서 데이터베이스 조회를 통해 실제로 맞는 사람인지, 사용 가능한 사용자인지의 정보를 받아오고, 세션 아이디값을 키로 유저 정보를 밸류로 저장함. 사용자 브라우저에는 세션 아이디를 반환해 쿠키에 저장하도록 함.

다음 단계로 요청을 보낼 때마다 모든 HTTP 요청에 자신의 세션 아이디를 포함시킴

서버에서 세션아이디의 값을 확인하고 세션 아이디에 소속된 유저 정보를 파악함으로써 가져옴

같은 도메인에서 만든 쿠키만 사용할 수 있다

 

HTTPS

TLS

  • HTTPS의 기반 기술
  • 컴퓨터 네트워크 상에 정보를 안전하게 공유하기 위한 암호화 규칙
  • 흔히 말하는 HTTPS는 HTTP에 TLS가 적용된 형태이다

암호화

  • 특정 규칙(알고리즘)을 가지고 평범한 데이터(평문)를 제3자가 확인할 수 없도록 정보를 숨기는(암호문) 과정

대칭키 암호화

  • 같은 키를 사용하여 암호화
  • 빠르고 자원 소모가 적음
  • 양측이 동일한 키를 가지고 있어야 함 (대칭키)

비대칭키 암호화 (공개키 암호화)

  • 서로 다른 키를 사용하여 암호화
  • 개인 키를 공개하지 않아 보안이 뛰어남
  • 하드웨어 자원 소모가 큼
  • 암호화 복호화 시간이 오래걸림
  • 공개키: 서비스에 접근할 때 공개키를 줌. 암호화를 진행할 때는 공개키를 사용.
  • 개인키: 서버 내부에서만 저장하고 사용하는, 공개되지 않는 개인 키.
  • 공개키를 사용하여 HTTP요청을 암호화 하고(암호문으로 바꾸고), 개인키를 사용하여 암호문을 복호화 함

TLS는 대칭키 암호화, 비대칭키 암호화 두 방법을 모두 사용

공개키 암호화의 보안과 대칭키 암호화의 속도를 동시에 만족하기 위해 고안된 방식

TLS가 적용되지 않은 서비스는 개인정보가 얼마든지 유출될 수 있음

브라우저가 서비스에 첫 요청을 보냄. 요청을 보낼 때 사용 가능한 암호화 방식을 알려달라고 요청을 보냄

서비스에서는 사용 가능한 암호화 방식 중 하나를 선택해서 서버 자신의 인증서와 함께 전달 (이 과정에서 공개키도 포함)

1차적인 요청이 진행되고 난 후

(브라우저에서 받아온) 서버의 공개키는 브라우저에 있고, 서버의 개인키는 서버에 있는 상태

브라우저에서는 서버의 공개키를 이용해서 임의의 대칭키를 만들어서 서버의 공개키로 암호화함

서버의 공개키로 암호화 했기 때문에 서버의 개인키가 없으면 대칭키 확인 불가능

암호화된 대칭키를 서버에 전송해서 서버에서 개인키를 활용해 대칭키를 확인함

공유된 대칭키를 이용해서 서버에서 응답을 암호화해서 브라우저에 전송

브라우저에서 만들었던 대칭키로 암호문을 다시 평문으로 바꾸고,

실제로 서비스를 제공받기 위한 요청을 대칭키로 암호화해서 서버에 전달,

이에 대한 응답을 서버에서 대칭키로 암호화해서 브라우저에 전달


Login 기본

@EnableWebSecurity: SpringSecurity의 설정을 조작할 준비가 되었다는 것을 Spring IoC에 알려줌. 설정들이 열리고 

configure 함수에 들어오는 HttpSecurity는 filter와 유사하게 생각할 수 있음

HttpSecurity 객체가 전체 어플리케이션을 관장하는 설정들을 들고 있는 객체

@Configuration bean을 통해서 http 객체에 원하는 값들을 함수를 이용해 추가해서 보안 설정을 조작할 수 있음 (빌더 패턴과 유사)

.authenticated(): 선언된 url들을 로그인된 사용자가 접근 가능하도록

.anonymous(): 로그인을 하지 않은 사용자가 접근 가능하도록

.permitAll(): 모든 사용자가 접근 가능하도록

.antMatchers(): url을 기준으로 어떤 것을 허용하고 허용하지 않을지

.defaultSuccessUrl(): 기본적으로 돌아가야 하는 페이지를 설정해주고 싶을 때

 

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/home/**")
                .anonymous()
                .anyRequest()
                .authenticated()
            .and()
                .formLogin()
                .loginPage("/user/login")
                .defaultSuccessUrl("/home")
                .permitAll()
        ;
    }
}

마지막에 .permitAll()이 있을 경우 위의 .authorizeRequests()보다 우선순위에서 작동함

-> /user/login 페이지의 경우 로그인 없이도 진행할 수 있음

 

.formLogin: 로그인 페이지를 사용하도록 HttpSecurity를 설정

 

Login 커스텀

UserDetailsService 만들어보기

사용자 관리를 어떻게 할 지 정하기 위해서는 configure(AuthenticationManagerBuilder) 메소드를 사용

AuthenticationManagerBuilder 없이 기본값으로 run하게 되면 default security password가 나옴

사용자의 username, 비밀번호가 일치하는지 등의 확인을 이 메소드에서 설정.

.inMemoryAuthentication(): AuthenticationManagerBuilder에 memory상에서 유저 검증을 하겠다는 뜻

 

 

UserDetails 사용하기

UserDetails 객체 안에 사용자의 닉네임, 비밀번호 같은 정보들이 들어감

.getContext() 함수를 사용하면 Authentication을 바로 받아올 수 있음 -> 이것을 IoC Container와 조합하면 어플리케이션 상의 어디에서든 사용할 수 있는 Authentication 변수를 받아올 수 있음

SecurityContextHolder는 자신이 실행되고 있는 thread를 기준으로 현재의 컨텍스트를 확인하기 때문에 동시에 여러개의 요청이 들어왔을 때 서로 같은 유저가 등장할 일은 없음(thread마다 다르게 등장하게 됨)


OAuth2와 JWT

Social Login, OAuth2

Single Sign On 기법

한 번의 로그인으로 여러 개의 다른 서비스에서 자신의 정보를 공유하는 것 (네이버 쇼핑, 네이버 메일, ...)

소셜로그인 개념이 등장하기 전부터 존재했음

여러 개의 도메인이 한 개의 인증 서버를 통해서 사용자 정보를 주고받을 수 있는 것

쿠키에 기한을 설정해서 어느 정도의 시간이 지나면 쿠키를 삭제하는 등의 방식으로 로그인이 더이상 유효하지 않도록 할 수 있음

주로 하나의 큰 기업에서 여러 개의 서비스에 대해 동일한 유저 정보를 유지하고 동일한 로그인 인터페이스를 유지하기 위해 사용 (연관성 있는 서비스끼리)

(왼쪽)서비스가 SSO 서버로 로그인 요청을 포워드함

로그인 페이지로 이동

로그인 페이지에서 사용자의 정보를 전달받고 로그인을 진행

로그인을 진행하면 사이트(도메인)의 쿠키에 로그인 정보를 저장 (쿠키에 세션 값이 들어가 있어 세션에 어떤 사용자가 들어가있는지를 관리)

sub-service에서 사용한 토큰을 반환함

쿠키는 도메인 별로 독립적이나, 토큰을 돌려주었기 때문에 토큰을 이용해서 서버에 요청하면 로그인 정보를 돌려줄 수 있음 (토큰으로 권한 확인)

토큰으로 권한을 확인한 후 상태를 자신의 쿠키에 저장함

(오른쪽)서비스가 SSO 서버로 로그인 요청을 포워드함

SSO 서버에 들어가는 순간 이미 로그인 되어 있다는 정보가 쿠키에 기록되어 있기 때문에 그 상태를 확인하고 토큰을 반환받음

반환받은 토큰으로 권한을 확인하고 상태를 자신의 쿠키에 저장

 

Social Login

연관성 없는 서비스가

 

OpenAuthorization(OAuth)

Naver Login 구현하기

redirect uri
// oauth2 서버에서 요청을 보내고 난 다음 액세스 토큰을 전달하는 uri를 무엇으로 설정할지

loadUser(): OAuth의 과정이 모두 이루어지고 난 후 userRequest가 해당 함수에 들어가는 순간 사용자의 정보가 돌아오게 됨

이 시점에서 사용자의 정보는 나의 서버에 들어와 있고, 이것을 정리해서 내 서비스에서 어떤 형태로 사용할 것인지 정의하기 위한 함수

 

OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();

만들어져 있는 DefaultOAuth2UserService에서 사용자의 요청을 대신 받아와주는 내용

JSON Web Token (JWT)

공개키 암호화를 이용하여 사용자 권한을 안전하게 주고받는 용도

인터넷 상에서 표준으로 사용되자고 제안된 형태

OAuth의 grant-type이 로그인을 해서 사용자 정보를 받아오는 grant-type 외에 api 아이디키를 제공함으로써 JWT를 반환받는 형태로 OAuth가 진행되기도 함

JWT를 들고 있는 대상은 자신이 할 수 있는 일에 대한 자격증을 소유하고 있다고 볼 수 있음

비밀키로 암호화, 공개키로 복호화


OAuth2 서버 만들어보기

 

'Java > project lion JSB the origin' 카테고리의 다른 글

Ch.10 Spring Cloud  (0) 2022.04.05
Ch.9 Spring과 Middlewares  (0) 2022.04.01
Ch.7 Spring Boot 기능활용 (2)  (0) 2022.03.13
Ch.6 Spring Boot 기능활용(1)  (0) 2022.03.04
Ch.5 CRUD & Data (2)  (0) 2022.03.01
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함