유튜브에서 스프링시큐리티를 심화교육하면서 조금더 레벨업 하고자 한다.
IDE : IntelliJ
언어 : Java 8
스프링부트 버전 : 2.7.13
DB : MySQL
빌드관리 도구 : Maven
OS : iOS
참고유튜브 : 메타코딩
JWT(Json Web Token)
정보를 Json 객체로 안전하게 전송하기 위한 방법
구조는 헤더(Header)/페이로드(Payload)/서명(Signature)
- 헤더(Header)
헤더에는 해시알고리즘과 토큰의 유형이 표시 되어있다.
- 페이로드(Payload)
페이로드에는 데이터(정보)들이 들어가 있다.
- 서명(Signature)
서명부분의 구조는 header.payload, 비밀키 로 되어있다.
JWT를 이용해서 로그인을 진행 한 후 개인정보페이지로 이동했을때의 진행과정은
1. 클라이언트 측 로그인요청
2. 서버 JWT생성 후 클라이언트 측으로 응답
3. 클라이언트 측 개인정보페이지 요청, 헤더에 JWT 첨부하여 서버측으로 전달
4. 전달받은 JWT를 이용하여 사용자 검증완료
5. 페이로드에 있는 회원정보로 db에서 검색 후 개인정보페이지 응답
JWT(Json Web Token)을 활용해보기 위해서 새로운 프로젝트를 생성한다.
mvnrepository에서 JWT 디펜더시도 추가
https://mvnrepository.com/artifact/com.auth0/java-jwt
pom.xml에 추가한다.
application.properties 를 yml으로 변경
application.yml에 아래내용 추가
server:
port: 8089
servlet:
context-path: /
encoding:
charset: UTF-8
enabled: true
force: true
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/security?serverTimezone=Asia/Seoul
username: 'root'
password: '1234'
jpa:
hibernate:
ddl-auto: create
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
show-sql: true
controller패키지에 RestApiController 클래스 추가
기존방법인 form로그인방식을 확인하기 위해서 간단한 주소 작성
@GetMapping("/home")
public String home(){
return "home";
}
서버를 실행하면 콘솔에 비밀번호가 나오게된다.
username은 user
password는 콘솔에 나온 비밀번호를 로그인해야 /home으로 이동할 수 있다.
그 후 db에 연결을 해준다.
스키마이름 Jwt으로 생성 후 db연결 후 IntelliJ에서 jwt스키마로 변경을 해준다.
DB로 이동해서 jwt를 생성해준다.
model 패키지에 User 모델 클래스 생성
아래와 같이 추가해준다.
@Entity
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String username;
private String password;
private String roles;
public List<String> getRoleList(){
if (this.roles.length()>0){
return Arrays.asList(this.roles.split(","));
}
return new ArrayList<>();
}
}
서버를 실행해주면 db에 user 테이블이 생성이 된다.
config패키지 생성 후 CorsConfig와 SecurityConfig 생성
CorsConfig에 규칙을 생성해낸다.
config.setAllowedOrigin("*") -> 모든 ip에 대해서 응답 허용
config.setAllowedHeader("*") -> 모든 header에 응답 허용
config.setAllowedMethod("*") -> 모든 post, get, patch, delete 요청 허용
source.registerCorsConfiguration("/api/**", config) -> /api로 들어오는 주소는 모드 해당 규칙을 따라야한다
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*") ;
config.addAllowedMethod("*");
source.registerCorsConfiguration("/api/**", config);
return new CorsFilter(source);
}
}
SecurityConfig에서 .formLogin().disable과 HttpBasic().disable()로 기본적인 Http 로그인과 form 로그인방식을 사용하지 않게 설정해준다.
addFilter로 CorsConfig에서 만든 필터설정을 넣어준다.
( 여기서 바보같이 return null로 설정해놓고 해당 필터가 작동이 되지 않아서 왜 안되는지 찾아보느냐 시간이 좀 걸렸다... )
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final CorsConfig corsConfig;
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception{
http.csrf().disable()
.addFilter(corsConfig.corsFilter())
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.formLogin().disable()
.httpBasic().disable()
.authorizeRequests()
.antMatchers("/api/v1/user/**")
.access("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')or hasRole('ROLE_MANAGER')")
.antMatchers("/api/v1/manager/**")
.access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')")
.antMatchers("/api/v1/admin/**")
.access("hasRole('ROLE_ADMIN')")
.anyRequest().permitAll();
return http.build();
}
}
서버를 실행해서 /home으로 이동해보면 로그인을 하라는 창이 나오지 않고 이동이 가능하다.
이미 로그인이 되어서 이동이 가능한거 아니야?
그렇다면 SecurityConfig에서 설정한 권한들이 있어야 특정 주소로 이동할 수 있게 만들었으니 해당 주소로 이동을 해보자
403 에러가 발생하면서 접근이 제한되었다.
제대로 잘 작동하는걸 확인할 수 있다.
'프로젝트 > SpringSecurity' 카테고리의 다른 글
[Spring Security] 12. JWT를 이용하기위한 임시토큰만들어 테스트해보기 (0) | 2023.07.12 |
---|---|
[Spring Security] 11. JWT를 이용하기위한 filter 등록 테스트 (0) | 2023.07.11 |
[Spring Security] 9. OAuth 네이버로그인 (0) | 2023.07.07 |
[Spring Security] 8. OAuth 페이스북로그인 (0) | 2023.07.06 |
[Spring Security] 7. OAuth 구글로그인(4) (0) | 2023.07.05 |
댓글