7. 스프링 시큐리티 기본 보안 구성
스프링 시큐리티 활성화하기
02
- 모든 HTTP 요청 경로는 인증(Authentication)되어야 합니다.
- 어떤 특정 역할이나 권한이 없습니다.
- 로그인 페이지가 따로 없습니다.
- 스프링 시큐리티의 HTTP 기본 인증을 사용해서 인증됩니다.
- 사용자는 하나만 있으며, 이름은 user입니다, 비밀번호는 암호화 됩니다.
8. 스프링 시큐리티 기본 보안 구성
스프링 시큐리티 활성화하기
02
로그인 페이지
타코 주문 페이지
/login
/design
http://localhost:8080/design
9. 스프링 시큐리티 구성목표
스프링 시큐리티 구성하기
03
- 스프링 시큐리티의 HTTP 인증 대화상자 직접 만든 로그인 페이지로 인증합니다.
- 다수의 사용자가 이용할 수 있어야 합니다.
- 서로 다른 HTTP 요청 경로마다 서로 다른 보안 규칙을 적용합니다.
(홈페이지 사용자 등록 페이지는 인증이 필요하지 않습니다.)
14. 공격 종류
스프링 시큐리티 구성하기
03
Dictionary attack (많이 쓰는 비밀번호를 하나씩 넣
어보자)
단어를 입력하여 암호를 알아내거나 해독하는 컴퓨터 공격법입니다. 암호를 알아내기 위한 공격은 사전의 단어를 순차적으로 입력하는 것입니다.
단어를 그대로 입력할 뿐 아니라, 대문자와 소문자를 뒤섞기도 하고, 단어에 숫자를 첨부하기도 하는 등의 처리도 병행하면서 공격을 할 수 있습니다.
Brute-force attack (사용가능한 문자열 내에서 무작위로 넣
어보자)
특정한 암호를 풀기 위해 가능한 모든 값을 대입하는 것을 의미합니다. 대부분의 암호화 방식은 이론적으로 무차별 대입 공격에 대해 안전하지 못하며, 충분한 시간이 존재한다
면 암호화된 정보를 해독할 수 있습니다. 하지만 대부분의 경우 모든 계산을 마치려면 실용적이지 못한 비용이나 시간을 소요하게 되어, 공격을 방지하게 합니다. 암호의 '취
약점'이라는 의미에는 무차별 대입 공격보다 더 빠른 공격 방법이 존재한다는 것을 의미합니다.
Rainbow Table (많이 쓰는 비밀번호의 Hash 값을 표로 만들어 놓고 넣어보자)
해시 함수를 사용하여 변환 가능한 모든 해시 값을 저장시켜 놓은 표이다. 보통 해시 함수를 이용하여 저장된 비밀번호로부터 원래의 비밀번호를 추출해 내는데 사용된다.
19. 커스텀 로그인 페이지 만들기
커스텀 로그인 페이지 만들기
04
커스텀 로그인 페이지 만들기
요청형식의 기본은 POST 메소드에 /login 경로로 로그인 요청을 처리하며 사용자 이름과 비밀번호 필드의 이름은 username과 password로 간주합니다.
SecurityConfig.java
login.html
22. 참고
Spring in Action 제 5판
SHA256 해시넷 (http://wiki.hash.kr/index.php/SHA256)
Spring Security_CSRF Token의 개념과 사용 방법 (https://codevang.tistory.com/282)
스크립트 알고리즘(http://wiki.hash.kr/index.php/스크립트_알고리즘)
Bcrypt (https://ko.wikipedia.org/wiki/Bcrypt)
[Spring Security] spring boot를 이용한 HTTP Basic Authentication (https://velog.io/@code12/Spring-Security-spring-boot를-이용한-HTTP-Basic-Authentication)
[스프링 핵심기술] - @Autowired (https://jjingho.tistory.com/6)
#4:스프링 시큐리티는 스프링 기반의 어플리케이션의 보안(인증과 권한)을 담당하는 프레임워크이다.
만약 스프링시큐리티를 사용하지 않았다면, 자체적으로 세션을 체크하고 redirect 등을 해야할 것이다.
스프링 시큐리티는 보안과 관련해서 체계적으로 많은 옵션들로 이를 지원해준다.
spring security는 filter 기반으로 동작하기 때문에 spring MVC 와 분리되어 관리 및 동작한다.
참고로 security 3.2부터는 XML로 설정하지 않고도 자바 bean 설정으로 간단하게 설정할 수 있도록 지원한다.
#5:기존 taco-cloud 프로젝트의 pom.xml파일에 dependency를 추가합니다.
첫 번째 dependency는 스프링 부트 보안 스타터 의존성이고,
두 번째는 보안 테스트 의존성입니다.
#6:설치가 완료된 후 애플리케이션을 시작하고 홈페이지에 접속해보면 스프링 시큐리티에서 제공하는 기본 로그인 페이지로 이동합니다.
#7:기본 아이디는 user이고 비밀번호는 애플리케이션 로그를 확인하면 비밀번호가 생성되어있는데
36자리 비밀번호를 복사하여 붙여넣고 Sign in 버튼을 누르면 로그인됩니다.
#8:security starter를 추가했을 때 다음의 보안 구성이 제공됩니다.
타코 클라우드를 포함해서 대부분의 애플리케이션에서 필요한 보안 기능은 이런 기본적인 보안 기능과 많이 다를 것이라고 생각됩니다.
애플리케이션 보안을 제대로 구축하려면 더 많은 작업이 필요하며, 최소한 다음 기능을 할 수 있도록 스프링 시큐리티를 구성해야합니다.
#11:장황한 XML 기반의 구성을 포함해서 그동안 스프링 시큐리티를 구성하는 방법은 여러가지가 있었습니다. 다행스럽게도 최근의 여러 스프링 시큐리티 버전에서는 훨씬 더 알기 쉬운 자바 기반의 구성을 지원합니다.
타코 클라우드 보안의 모든 요구사항은 자바기반의 스프링 시큐리티 구성으로 구현하게 될 것입니다.
SecurityConfig 클래스의 역할은 사용자에 HTTP 요청 경로에 대해 접근 제한과 같은 보안 관련 처리를 우리가 원하는 대로 할 수 있게 해줍니다.
코드를 작성한 후 http://localhost:8080 에 다시 접속해보면 로그인 페이지로 이동하지 않고 홈페이지가 바로 나타나게 됩니다.
에서 모든 사용자의 홈페이지 접근을 허용했기 때문입니다.
다음은 한 명이상의 사용자를 처리할 수 있도록 사용자 정보를 유지관리하는 사용자 스토어를 구성하겠습니다.
#12:사용자 정보를 유지 관리할 수 있는 곳 중 하나가 메모리입니다.
변경이 필요 없는 사용자만 미리 정해놓고 애플리케이션을 사용한다면 아예 보안 구성 코드 내부에 정의할 수 있을 것입니다.
{noop} 은 텍스트 그대로 비밀번호를 인식하게 해줍니다. 붙이지 않으면 다른 인코딩으로 암호화를 해주어야 합니다.
스프링 5부터는 반드시 비밀번호를 암호화 해야하므로 만일 password() 메서드를 호출하여 암호하하지 않으면 접근 거부(HTTP 403) 또는 Internal Server Error(HTTP 500)가 발생됩니다.
인메모리 사용자 스토어는 테스트 목적이나 간단한 애플리케이션에서는 편리하다. 그러나 사용자 정보의 추가나 변경이 쉽지 않습니다. 즉, 사용자의 추가, 삭제, 변경을 해야 한다면 보안 구성 코드를 변경한 후 애플리케이션을 다시 빌드하고 배포해야 합니다.
#13:사용자 정보는 관계형 데이터베이스로 유지 관리 되는 경우가 많으므로 JDBC 기반의 사용자 스토어가 적합해 보입니다.
데이터베이스를 액세스하는 방법을 알 수 있도록 dataSource()메서드를 호출합니다. 애노테이션을 지정했으므로 DataSource가 자동으로 주입됩니다.
usersByUsernameQuery()와 authoritiesByUsernameQuery()메서드를 사용하여 사용자 정보와 권한 쿼리를 사용하였습니다.
groupAuthoritiesByUsername()을 호출하면 그룹 권한 쿼리도 사용할 수 있습니다.
그리고 passwordEncoder() 메서드를 호출하여 비밀번호 인코더를 지정합니다.
1. Autowired란
필요한 의존 객체의 “타입"에 해당하는 빈을 찾아 주입한다.
생성자
setter
필드
위의 3가지의 경우에 Autowired를 사용할 수 있다. 그리고 Autowired는 기본값이 true이기 때문에 의존성 주입을 할 대상을 찾지 못한다면 애플리케이션 구동에 실패한다.
#14:어떤 인코더를 사용하든, 일단 암호화되어 데이터베이스에 저장된 비밀번호는 암호가 해독되지 않는다.
대신 로그인 시에 사용자가 입력한 비밀번호화 동일한 알고리즘을 사용해서 암호화된다.
그다음에 데이터베이스의 암호화된 비밀번호와 비교되며
이 일은 PasswordEncoder의 matches() 메서드에서 수행됩니다.
#15:사전 공격(Dictionary attack)은 사전에 있는 단어를 입력하여 암호를 알아내거나 해독하는 컴퓨터 공격법이다. 암호를 알아내기 위한 공격은 사전의 단어를 순차적으로 입력하는 것이다. 단어를 그대로 입력할 뿐 아니라, 대문자와 소문자를 뒤섞기도 하고, 단어에 숫자를 첨부하기도 하는 등의 처리도 병행하면서 공격을 할 수 있다.[1]
수십만 개의 단어가 수록되어 있는 사전을 컴퓨터에 자동 처리시킴으로써 짧은 시간 안에 모든 단어를 입력할 수 있기 때문에 사전단어공격은 기본적인 패스워드 탐색의 수법으로 이용된다. 이에 대처하기 위해서는 인명이나 의미가 있는 단어를 패스워드로 쓰지 말아야 하며, 기호나 숫자 등을 랜덤으로 결합시키는 방법을 사용해야 한다.
#16:SHA-256 해시 함수는 어떤 길이의 값을 입력하더라도 256비트의 고정된 결과값을 출력한다.
일반적으로 입력값이 조금만 변동하여도 출력값이 완전히 달라지기 때문에 출력값을 토대로 입력값을 유추하는 것은 거의 불가능하다.
출력 속도가 빠르다는 장점을 갖고 있다. 또한 단방향성의 성질을 띄고 있는 암호화 방법으로 복호화가 불가능하다.
SHA는 일반적으로 GPU연산에 유리한 32비트 논리 및 산술 연산만 사용하기 때문에, 공격자가 빠른연산으로 공격할 수 있기 때문입니다.
#17:해시 함수의 컨테이너인 PBKDF2는 솔트를 적용한 후 해시 함수의 반복 횟수를 임의로 선택할 수 있다. PBKDF2는 아주 가볍고 구현하기 쉬우며, SHA와 같이 검증된 해시 함수만을 사용한다.
#18:scrypt는 PBKDF2와 유사한 adaptive key derivation function이며 Colin Percival이 2012년 9월 17일 설계했다. scrypt는 다이제스트를 생성할 때 메모리 오버헤드를 갖도록 설계되어, 억지 기법 공격(brute-force attack)을 시도할 때 병렬화 처리가 매우 어렵다. 따라서 PBKDF2보다 안전하다고 평가되며 미래에 bcrypt에 비해 더 경쟁력이 있다고 여겨진다. scrypt는 보안에 아주 민감한 사용자들을 위한 백업 솔루션을 제공하는 Tarsnap에서도 사용하고 있다. 또한 scrypt는 여러 프로그래밍 언어의 라이브러리로 제공받을 수 있다.
오버헤드는 어떤 일을 처리하기 위해 들어가는 간접적인 처리시간.메모리 등을 말한다.
#19:bcrypt는 애초부터 패스워드 저장을 목적으로 설계되었다.
Niels Provos와 David Mazières가 1999년 발표했고 현재까지 사용되는 가장 강력한 해시 메커니즘 중 하나이다.
bcrypt는 보안에 집착하기로 유명한 OpenBSD에서 기본 암호 인증 메커니즘으로 사용되고 있고 미래에 PBKDF2보다 더 경쟁력이 있다고 여겨진다.
#20:기본 로그인 페이지를 교체하려면 우선 우리의 커스텀 로그인 페이지가 있는 경로를 스프링 시큐리티에 알려주어야한다.
이것은 configure(HTTPSecurity) 메서드의 인자로 전달되는 http 변수에 formLogin을 호출해서 할 수 있다.
#21:CSRF 공격(Cross Site Request Forgery)은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 만드는 공격입니다.
사용자가 웹사이트에 로그인한 상태에서 악의적인 코드가 삽입된 페이지를 열면 공격 대상이 되는 웹사이트로 자동으로 폼이 제출되고 이 사이트는 위조된 공격 명령이 믿을 수 있는 사용자로부터 제출된 것으로 판단하게 되어 공격에 노출됩니다.
#22:CSRF 공격을 막기 위해 애플리케이션에서는 폼의 숨김(hidden) 필드에 넣을 CSRF 토큰을 생성할 수 있습니다. 그리고 해당 필드에 토큰을 넣은 후 나중에 서버에서 사용합니다.
이후에 해당 폼이 제출될 때는 폼의 다른 데이터와 함께 토큰도 서버로 전송됩니다.
그리고 서버에서는 이 토큰을 원래 생성되었던 토큰과 비교하며, 토큰이 일치하면 해당 요청의 처리가 허용됩니다.
스프링 시큐리티에는 내장된 CSRF 방어 기능이 있습니다. 또한 이 기능이 기본으로 활성화 되어있어서 별도로 구성할 필요가 없습니다. 단지 CSRF 토큰을 넣을 _csrf라는 이름의 필드를 애플리케이션이 제출하는 폼에 포함시키면 됩니다.
게다가 스프링 시큐리티에서는 CSRF 토큰을 넣는 것조차 쉽게 해줍니다. _csrf라는 이름의 요청 속성에 넣으면 되기 때문입니다.