SecurityFilterChain:
import org.springframework.security.web.SecurityFilterChain;
。Spring Security에서 제공하는 보안 filter 모음 역할의Interface.
(Authentication Filter,Authorization Filter,CORS Filter,CSRF Filter,ExceptionTranslation Filter등)
。Web Security Configuration를 정의하는@Configuration Class를 통해Spring Bean으로 등록 시Delegating Filter Proxy를 통해Servlet Filter Chain사이에서Filter로서의존성 주입되어 기능
。Spring Security의 핵심이 되는 기능을 제공하여 사용자에게 적절한Authentication과Authorization이 부여
。SecurityFilterChain의구현체로서HttpSecurity가 존재
▶FilterChain을 통해 설정 후HttpSecurity객체.build()로 생성된HttpSecurity instance를 반환하여SecurityFilterChain으로서Spring Bean으로 등록
▶ 이후@EnableWebSecurity에 의해 해당Spring Bean이 활성화
。Filter Chain의 경우Filter에 따른검증이 순차적으로 적용.
1.CORS,CSRF등의 Filter :
。기본필터
2.Authentication Filter:
。적절한자격증명보유 여부 Filtering
3.Authorization Filter:
。접근하려는자원에 적절한접근권한이 있는지 Filtering
Security Filter Chain핵심적인 기능
。기본적으로Controller에Mapping된 모든URL을 대상으로보호를 수행
▶ 해당URL에 대해요청시 사용자에게인증정보를 요구
。 승인되지 않은요청에 대해서는로그인 양식이 표현
▶URL로Http Request가 전송되었을때,SecurityFilterChain의필터를 통해 사용자가인증( Authenticate )되지 않은 경우,Login Form을 표시
HttpSecurity
。특정HTTP Request에 대한웹보안의Configuration을 설정하는 역할의SecurityFilterChain 인터페이스 구현체
▶Default로서 모든Http Request에 대해 적용
。Resource(URL)의접근 권한을 설정
▶ 특정Resource의접근 권한또는특정 권한을 가진사용자의접근 권한을 설정
。Spring Security의 각종Configuration을 수행.
▶@Configuration Class의@Bean Method에서HttpSecurity객체에서Filter Chain을 구현 후HttpSecurity객체.build()로HttpSecurity객체를 생성 및SecurityFilterChain객체로서 return하여Spring Bean으로서Spring Security의 설정을 반영.
。Spring Security 6.x부터는 람다기반 설정방식 권장
httpsecurity객체.authorizeHttpRequest(람다식):
。HttpRequest에 대한 접근권한을 설정하는 Method.
▶HttpRequest을 특정 패턴에 따라서 filtering하고 접근권한을 부여
。특정HttpSecurity객체에 대하여 input된 인증이 된 모든HttpRequest에 대하여 승인처리 설정.
▶ 구현하지 않는 경우, 모든HTTP Request에 대해서 거절하면서Authentication을비활성화
。콜백함수의 매개변수로auth를 전달하며, 해당 변수를 통해 Application의API호출에 따른 모든HttpRequest에 대한 접근권한 설정이 가능.
HTTP Request의 접근권한설정 Method (Global Security)
。HttpSecurity.authorizeHttpRequests(람다식)에서람다식이 전달하는인자( =auth)를 통해 설정.
▶ 구현하지 않는 경우, 모든HTTP Request에 대해서 거절하면서 Authentication을 비활성화
auth.requestMatchers( HTTPMethod.메소드명 , "/URL Pattern")
。HTTP Request의 특정URL pattern과HTTP Method에 대해서 접근 권한을 설정
▶ 나머지HTTP Request에 대해서는auth.anyRequest()에서 정의
ex)auth.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll():
▶ 모든URL Pattern의OPTIONS HTTP Method방식의HTTP Request는 모두 허용.
auth.hasRole("ROLE역할명")
。특정Role을 가진 사용자만 접근할 수 있도록 제한.http.authorizeHttpRequests(auth -> auth .requestMatchers("/admin/**").hasRole("ADMIN") )▶
/admin/**URL Pattern은"ROLE_ADMIN"을 가진 사용자만 접근 가능.
auth.anyRequest():
。따로 접근권한을 설정한 특정HTTP Request이외의 모든HTTP Request에 대한 접근권한을 정의http.authorizeHttpRequests( auth->auth.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() .anyRequest().authenticated() )▶
auth.requestMatchers에서 정의한HTTP Request이외의 모든HTTP Request에 대해 인증된 사용자만 접근가능하도록 설정.
auth.anyRequest().authenticated()
。모든HTTP Request에 대해Authenticated된 Client만 접근가능하도록 설정.
auth.anyRequest().permitAll()
。모든HTTP Request에 대해 허용.
▶ 따로 접근권한을 설정한 특정HTTP Request가 없는 경우 보안없이 개방하는것과 같음.
auth.anyRequest().denyAll()
。모든HTTP Request에 대해 차단.
httpsecurity객체.formLogin(Customizer.withDefaults())
。HttpRequest에 대한Spring Security의 기본Web Login Form(HTML Login Page)을 활성화하는 method.
▶ Cilient가 Application에 접근할 때 로그인 페이지를 제공하고, 로그인 요청을 처리하는 기능 수행.
Customizer.withDefaults():formLogin()에 관련된 기본값 사용설정.
▶withDefaults()는 Customizer class의 static method로서 정의됨.
。JWT을 인증방식으로 사용하면서Session비활성화 된 경우 Session 기반 인증을 수행하여Session을 통해 로그인 상태를 유지하는formLogin()을 사용할 필요가 없으므로 비활성화.
HttpSecurity객체.httpBasic(Customizer.withDefaults())
。Spring Security에서HTTP Basic Authentication을 활성화하는 Method.
▶ Clent의 ID와 PW를HTTP Request의Authorization Header에 포함하여 인증하는 방식.
。Authorization Header요구 시Basic Authentication도출.
Basic Authentication: 웹브라우저의 인증 팝업으로Authorization Header의ID/PW입력 기능 제공.
。HTTP Basic:Header에 ID와 PW를 포함 및Base64로 인코딩하여HTTP Authorization Header에 포함하여 Server로 전송.
httpsecurity객체.csrf(콜백함수)
。HttpRequest에 대한CSRF Protection을 설정하는 method.
▶Spring Security는CSRF Protection이 기본적으로 활성화되어있으므로, 해당 method를 이용해 비활성화 설정이 가능.
。람다식의 매개변수로서CSRFinstance가 input.http.csrf(csrf->csrf.disable());▶ 다음 코드는 다음처럼
메서드참조로 축약이 가능.csrf(AbstractHttpConfigurer::disable)。특정
HttpSecurity객체에 대하여CSRF Protection이 비활성화.
。Session이 존재하지 않는 경우(Stateless)에만 비활성화하며,Session이 존재하는 경우, 반드시CSRF protection을 활성화해야한다.
▶ Spring Security에서는 default로CSRF protection활성화로 설정되어있음.
HttpSecurity객체.headers(콜백함수)
。HttpRequest에 대한Http Response Header를 설정하는 method.
▶Spring Security는 보안 관련HTTP Header를 자동으로 추가하지만,
필요에 따라 추가하거나 비활성화 설정 가능.
。람다식의 매개변수로서Http header객체가 전달http.headers(header -> header.frameOptions(frameOptions->frameOptions.disable()));
header객체.frameOptions(람다식):
。HTTP Header을 통해Web Application의iframe보안정책을 설정하는 기능.
▶ 주로Clickjacking공격을 방지하는 역할을 수행.
。frameOption객체가람다식 인자로 전달됨
<iframe>:inline frame
。HTML에서 다른 웹페이지나 문서를 현재 페이지 내에 삽입할 때 사용하는 태그.
▶ 외부 웹사이트, 동영상, 지도, 문서등을 포함 가능
frameoption객체.disable():
。Http Header의FrameOption을 비활성화.
▶ 모든iframe을 허용하여iframe기반 UI ( ex.h2-console)을 사용 시 필요하지만 보안위험이 존재하므로, 신뢰할 수 있는 경우에만 사용.
frameoption객체.sameOrigin():
。iframe을 같은 도메인에서 오는 `HTTP Request에 대해서만 허용.
▶ 동일한 도메인에서만iframe을 사용가능하고, 다른 도메인에서는 차단.
HttpSecurity객체.build():
。Configuration이 수행된HttpSecurity객체를 생성.
▶ 주로SecurityFilterChain Interface로UpCasting하여 활용.
HttpSecurity객체.sessionManagement(콜백함수):
。Spring Security에서Session Policy를 설정하는 Method.
。Spring Security는 기본적으로Session을 사용하여 사용자의Authentication 정보를 저장하지만,Session을 사용하지 않는Stateless방식의JWT기반 인증 또는REST API구현을 위해Session Policy에서STATELESS설정 시 활용
▶Session이 없는 경우,CSRF Protection을 비활성화 가능
。HttpSecurity객체.formLogin()등의Session을 사용하는 인증방식의 경우 사용설정해야한다.
▶ 웹브라우저에 계속 로그인 상태를 유지해야하는 경우Session을 통한 로그인을 활성화
▶REST API처럼 API 호출시에만 일회성으로 로그인이 필요한 경우Session을 사용하지 않는STATELESS방식으로JWT를 활용.
。매개변수로session이 전달되며, 람다식으로session.sessionCreationPolicy(Session Policy 설정 옵션)를 통해Spring Security가 설정한Session Policy에 따라Session의 처분을 결정.httpsecurity객체.sessionManagement( session->session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) )▶
Spring Security가Session을 사용하지 않도록Session Policy설정.
Session Policy설정 옵션
import org.springframework.security.config.http.SessionCreationPolicy;
SessionCreationPolicy.ALWAYS:
。항상 새로운Session을 생성하도록Session Policy설정.
SessionCreationPolicy.NEVER:
。Spring Security가Session을 생성하지 않지만, 기존Session을 사용가능하도록Session Policy설정.
SessionCreationPolicy.IF_REQUIRED:
。기본값으로서, 필요한 경우에만Session을 생성하도록Session Policy설정.
SessionCreationPolicy.STATELESS:
。Session을 사용하지 않도록Session Policy설정.
。주로JWT Token을 활용하는REST APIAuthentication 구현 시 사용.
HTTPSecurity객체.oauth2Login(Customizer.withDefaults())
OAuth - Google 로그인 설정
。Spring Security에서Oauth 2.0로그인 기능을 활성화.
▶ 다음 설정을 끝낸 후localhost:8080/login접속 시 해당 API를 보호하기위해 등록된OAuth2 Provider( ex.
。localhost:8080/logout접속 시 로그아웃을 수행.
HTTPSecurity객체.oauth2ResourceServer(람다식)
。OAuth2.0 Resorce Server를 이용하여HTTP Request의Authentication Header에 포함된Access Token( ex.JWT,Opaque Token등 )을 전달받아JWT Decoder의 Instance에 의해Decryption을 수행 및 유효성 검증을 수행하여Authentication하는 Method.
▶ 검증을 수행한 후Authentication된HTTP Request에 대해서만API에 접근할 수 있도록 처리.
。HttpSecurity객체.oauth2ResourceServer(람다식)의 람다식 매개변수는OAuth2ResourceServerConfigurer객체를 매개변수로 전달.
▶ 해당 Instance에서.jwt(),.opaqueToken()을 설정하여Resource Server의Access Token검증방식 선택.
。JwtDecoder Interface의 구현체의 Instance를 생성하는@Bean Method를 정의하여Encrypt된JWT Token을Decrypt후 유효성을 검증하는 역할을 수행
▶JWT를Decryption및 검증하는 용도로 활용되므로,JWK URI에서Key를 가져와서Decrypt를 수행하는JwtDecoder Instance를 생성하여 반환.@Configuration public class JwtSecurityConfiguration { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { // OAuth2.0 Resorce Server를 통해 HTTP Request의 JWT를 Decryption하여 return http.oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt .decoder(jwtDecoder()) )) // HttpSecurity instance를 생성한 후 return. // HttpSecurity는 SecurityFilterChain interface의 구현 Class이므로 // SecurityFilterChain의 instance로 활용이 가능. .build(); } // JWT는 RSA로 Encrypt 된 상태이므로 JWK URI 에서 Key를 가져와서 // Decrypt 및 유효성을 검증하는 JwtDecoder Instance를 생성하는 @Bean Method. @Bean public JwtDecoder jwtDecoder() { return NimbusJwtDecoder.withJwkSetUri("https://auth-server-url/.well-known/jwks.json").build(); } }
OAuth2ResourceServerConfigurer
。Spring Security에서OAuth2.0 Resource Server의Configuration을 수행하는 용도로 사용.
▶OAuth2.0 Access Token을 검증하는 보안필터를 설정.
。HTTPSecurity객체.oauth2ResourceServer(람다식)의 람다식 매개변수로서OAuth2ResourceServerConfigurerInstance가 전달
▶ 해당 Instance에서.jwt(),.opaqueToken()을 설정하여Resource Server의Access Token인증방식 선택
OAuth2ResourceServerConfigurer객체.jwt(람다식)
。OAuth2.0 Resource Server에서JWT기반 Authentication을 수행하는 Method.
▶Resource Server가JWT Token을 검증하도록 설정.
。일반적으로Resource Server에 의해HTTP Request의JWT를Custom JWT Decoder를 통해Decrypt하여 검증하는 용도로 사용.
。람다식 매개변수는JwtConfigurer객체를 받는다.
▶JwtConfigurer.decoder(JwtDecoder구현체Instance)를 통해JWT Decoder설정
JwtConfigurer
。JWT기반Authentication Configuration을 수행.
▶ 주로JWT Token을Decryption하는 용도로 사용됨.
。OAuth2ResourceServerConfigurer.jwt(람다식)의 람다식 매개변수로JwtConfigurer instance가 전달됨.
JwtConfigurer객체.decoder(JwtDecoder구현체Instance)
。JWT의Decryption을 수행하는JWT Decoder를 설정.
JwtDecoder
。RSA를 통해Encrypt된JWT Token을Decrypt및 유효성을 검증하는 역할을 수행하는Interface
▶NimbusJwtDecoder등의 구현 Class의instance를 생성하여JwtDecoder의 instance로 반환하는Custom JWT Decoder @Bean Method를 정의하여OAuth2ResourceServerConfigurer객체.jwt(람다식)에 활용.
。RSA를 통해Encrypt된JWT Token을Decrypt시Public Key가 필요하므로,JWK URI에서Key를 가져와서Decrypt를 수행.
▶JWT Signature의 검증을 수행하기 위해서Public Key가 필요하므로JWK를 활용한다.// JWT는 RSA로 Encrypt 된 상태이므로 JWK URI 에서 Key를 가져와서 // Decrypt 및 유효성을 검증하는 JwtDecoder Instance를 생성하는 @Bean Method. @Bean public JwtDecoder jwtDecoder() { return NimbusJwtDecoder.withJwkSetUri("https://auth-server-url/.well-known/jwks.json").build(); }
Nimbus JOSE+JWTLibrary :
。OAuth2.0 Resource Serverdependency를 추가할 경우 자동으로 같이 추가됨.
。Java에서JWT,JWK,JWE( JSON Web Encryption ) ,JWS( JSON Web Signature )를 쉽게 다룰 수 있도록 지원하는 오픈소스 Library.
▶JWT의 검증 ,Encryption & Decryption,Public Key관리 등의 기능을 제공하는 도구.
。Spring Security는 기본적으로Nimbus Library를 활용하여JWT를Decrypt.
NimbusJwtDecoder:
。Spring Security에서 제공하는JWT Decoder로서JWT를Decrypt및 유효성 검증을 수행하며JwtDecoderInterface를 구현한 기본 Class
▶JWK URI,RSA Public Key등을 통해JWT의Signature를 검증.
NimbusJwtDecoder.withJwkSetUri("JWK URI")
。RSA암호화 알고리즘을 사용하는JWT를Decrypt및Signature의 유효성 검증 시 사용하는NimbustJwtDecoder의 instance를 생성하는static Method.
▶JWK Set을 제공하는Authentication Server가 정의된JWK Set URI를 정의하여 자동으로Public Key를 가져온 후Decrypt및JWT Signature의 유효성 검증을 수행하는JwtDecoderInstance를 생성
。JWK Set URI:JWK Set을 제공하는 URI
https://example.com/oauth2/jwks:OAuth 2.0 Authentication Server가 제공하는 공개 키 목록.
NimbusJwtDecoder.withPublicKey(RSAPublicKey객체):
。RSA암호화 알고리즘을 사용하는JWT의Decrypt및Signature의 유효성 검증을 수행하는NimbusJwtDecoder instance를 특정RSAPublicKeyinstance를 활용하여 생성하는 Method.
▶ Client가JWT를 Server에 전송 시 Server는 해당Public Key기반ㅇ로 생성된NimbusJwtDecoderinstance를 통해 전송된JWT Signature를 유효성 검증 가능.
NimbusJwtDecoder.build():
。NimbusJwtDecoder의 instance를 생성하는builder method
▶NimbusJwtDecoder는JwtDecoder의 구현 Class이므로 해당Interface의 instance로서 활용 가능.