반응형
1) springSecurity 정의
1) 정의
- 웹 애플리케이션의 보안을 담당하는 프레임워크
- 애플리케이션에서 인증(Authentication)과 권한(Authorization)을 처리하는 기능 제공
- 이를 통해 로그인, 접근 제어, 보안 정책 쉽게 구현 가능
2) 인증과 권한
(1) 인증(Authentication)
- 사용자의 신원을 확인하는 과정
- 일반적으로 로그인이 이에 해당함
(2) 권한(Authorization)
- 사용자가 특정 리소스에 접근할 수 있는 권한이 있는지 확인
- 예: 일반 사용자는 관리자 페이지에 접근할 수 없음
작업
일단 pom.xml의 DB관련설정은 주석처리해보자
커스텀로그인
- Spring Security의 환경설정 코드를 구성할때 주로 사용
- 람다식이 아닌 코드를 찾는다면 적용이 불가능할 가능성 높음
- authorizeHttpRequests 메소드에 전달되는 객체를 requests라고 이름 지어
적용
2) 프로젝트생성 및 security적용
스프링부트로만들고 maven기반의 프로젝트로만들어주자
해당 의존성추가하기
applcation.properties
spring.application.name=springSecurity2
server.port=8080
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/gdjdb
spring.datasource.username=gduser
spring.datasource.password=1234
spring.jpa.hibernate.ddl-auto=update
#entity명이 낙타표기법이라면 _ 로 구분해저장
#spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
#entity명 평문으로 저장
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
controller/HomeController
package springSecurity2.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller("/")
public class HomeController {
@GetMapping
public String root(Model model) {
model.addAttribute("msg","홈으로이동합니다");
return"home";
}
@GetMapping("home")
public String home(Model model) {
model.addAttribute("msg","home");
return "home";
}
@GetMapping("my")
public String my(Model model) {
model.addAttribute("msg","my");
return "home";
}
@GetMapping("admin")
public String admin(Model model) {
model.addAttribute("msg","admin");
return "home";
}
@GetMapping("login")
public String login(Model model) {
return "login";
}
}
각각 다른url요청을 받지만 반환값은 같음
resourse/ templates/ home 은 그냥 msg만 띄워주는용도로 만들어놨으므로 생략
config/SecurityConfig
@Configuration
@EnableWebSecurity //Spring Security를 활성화
public class SecurityConfig {
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
/*
HttpSecurity : spring Security 보안설정 담당객체 (HTTP요청시 인증,권한을 정의가능)
authorizeHttpRequests : 요청 URL에 따라 권한설정
requestMatchers : 요청url
permitAll() : 모두허용
anyRequest() : 그 외의 모든요청
authenticated : 인증받아야함
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((auth)->auth
.requestMatchers("/","/home").permitAll() //home은 누구나 접근가능하다
.anyRequest().authenticated());
return http.build();
}
}
요약 : /g혹은 /home 으로 요청된 URL은 누구나 접근이 가능하다
다른 요청 URL은 인증이 필요하다
/ or /home으로 접근시
/my or /admin or /xx 접근시
3) 커스텀로그인 , 로그아웃
config/SecurityConfig의SecurityFilterChain메서드의 일부분
package springSecurity2.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.session.HttpSessionEventPublisher;
@Configuration
@EnableWebSecurity //Spring Security를 활성화
public class SecurityConfig {
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
/*
HttpSecurity : spring Security 보안설정 담당객체 (HTTP요청시 인증,권한을 정의가능)
authorizeHttpRequests : 요청 URL에 따라 권한설정
requestMatchers : 요청url
permitAll() : 모두허용
anyRequest() : 그 외의 모든요청
authenticated : 인증받아야함
*/
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
...............
//커스텀로그인
//loginPage("/login")로 인해 인증되지 않은 사용자가 보호된 URL에 접근하면 /login으로 리다이렉트됩니다.
http.formLogin((a)->a.loginPage("/login") //로그인요청
.loginProcessingUrl("/loginProc").permitAll()); //로그인 form의 action값
http.logout((a)->a.logoutUrl("/logout")
.logoutSuccessUrl("/login") //성공시 login 페이지로
.invalidateHttpSession(true)//세션초기화
.deleteCookies("JSESSIONID")//JSESSIONID(session)삭제
.permitAll());//누구나 접근가능
return http.build();
}
@Bean
public BCryptPasswordEncoder bcryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
알아야할것!
페이지에 session이 등록됐다면 cookie의 JSESSIONID가 활성화
http.formLogin((a)->a.loginPage("/login").....)으로 인해
인증되지않은 사용자가 보호된 URL로접근하면 login페이지로 강제 리다이렉트 되게 됨
4) BCrypt(security에서 제공)
테스트코드를 이용해 BCrypt가 무엇인지 설명하겠음
일단 Bcrypt는 단방향 암호화키라고 보면 됨
(평문으로 복호화가 불가능 하며 matches를 통해 비교만할수있다)
package springSecurity2;
import org.junit.jupiter.api.Test;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class TestBcrypt {
public static void main(String[] args) {
System.out.println("new BCryptPasswordEncoder().encode('123');");
String encode = new BCryptPasswordEncoder().encode("123");
String encode2= new BCryptPasswordEncoder().encode("123");
System.out.println("123 -> : "+encode);
System.out.println("123 -> : "+encode2);
System.out.println("\n검증은 BCryptPasswordEncoder().matches(암호화x,암호화O)");
boolean matches1 = new BCryptPasswordEncoder().matches("123", encode);
boolean matches2 = new BCryptPasswordEncoder().matches("15523", encode);
System.out.println("123? : "+matches1);
System.out.println("15523? : "+matches2);
}
}
다음과같은 출력이 나오게 됨
new BCryptPasswordEncoder().encode('123');
123 -> : $2a$10$OvaTYKPHADa8DzH0zdkLBufKpHvK1dyJI7lYTZZ66eJjbknlkJZvq
123 -> : $2a$10$hnVENFmS.uWV8IPc/IX8E.H0mGR9mo258sfMR7cHbKq1tntupWZ0e
검증은 BCryptPasswordEncoder().matches(암호화x,암호화O)
123? : true
15523? : false