💐 Spring/Spring Security

6. JWT를 사용하기 위한 프로젝트 세팅

iseunghan 2021. 10. 31. 22:08
반응형

이 포스트는 데어 프로그래밍님의 유튜브 강의를 듣고 나서 정리한 글입니다.

 

dependency 추가

  • Maven
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.16.0</version>
</dependency>

 

  • Gradle
// https://mvnrepository.com/artifact/com.auth0/java-jwt
implementation group: 'com.auth0', name: 'java-jwt', version: '3.16.0'

 

 

application.yml 설정

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: "jdbc:mysql://localhost:3306/JwtTutorial"
    username: "root"
    password: "1234"

  jpa:
    hibernate:
      ddl-auto: create
    database: mysql
    show-sql: true

jpa, db 설정 말고는 딱히 해줄건 없다..

 

User 생성

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String password;
    @Enumerated(EnumType.STRING)
    private USER_ROLES roles;

}

 

USER_ROLES

public enum USER_ROLES {
    ROLE_ADMIN, ROLE_USER
}

 

SecurityConfig

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CorsFilter corsFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // Session을 사용하지 않고, Stateless 서버를 만들겠다는 의미
                .and()
                .addFilter(corsFilter)  // Cross-Origin 정책 사용 X 모든 요청 허용 ** @CrossOrigin과의 차이점 : @CrossOrigin은 인증이 없을 때 문제, 그래서 직접 시큐리티 필터에 등록!
                    .formLogin().disable()
                    .httpBasic().disable()
                .authorizeRequests()
                    .antMatchers("/api/v1/user/**")
                        .hasAnyRole("USER", "MANAGER", "ADMIN")
                    .antMatchers("/api/v1/manager/**")
                        .hasAnyRole("MANAGER", "ADMIN")
                    .antMatchers("/api/v1/admin/**")
                        .hasRole("ADMIN")
                    .anyRequest().permitAll()
                ;
    }
}
  • csrf().disable() : 공격자가 사용자가 의도치 않은 요청(csrf)을 수행하게 하는 것을 disable한다.
  • sessionManagement().sessionCreationPolicy(SessionCreatationPolicy.STATLESS) : Session을 사용하지 않고, 서버를 Stateless하게 구성하겠다는 의미
  • formLogin(), httpBasic() : disable
  • "/api/v1/user/**" 로 들어오는 모든 요청은 USER, MANAGE, ADMIN 권한이 있어야 한다.
  • "/api/v1/manager/**" 로 들어오는 모든 요청은 MANAGE, ADMIN 권한이 있어야 한다.
  • "/api/v1/admin/**" 로 들어오는 모든 요청은 ADMIN 권한이 있어야 한다.
  • 그 외 나머지 요청은 모두 허용한다.

 

CorsConfig

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);   // 내 서버가 응답을 할 때 응답해준 json을 자바스크립트에서 처리할 수 있게 할지를 설정
        config.addAllowedOrigin("*");       // 모든 ip에 응답 허용
        config.addAllowedHeader("*");       // 모든 header에 응답 허용
        config.addAllowedMethod("*");       // 모든 HTTP Method 요청 허용

         source.registerCorsConfiguration("/api/**", config);    // /api/** 로 들어오는 모든 요청들은 config를 따르도록 등록!

        return new CorsFilter(source);
    }
}
  • CORS(Cross-Origin Resource Sharing) : 쉽게 말해 도메인이 다른 서버로 리소스 요청을 보내면 CORS 정책을 위반하기 때문에 에러 발생!
  • 해결 방법 ?
    1. CorsConfiguration 객체를 생성하여, 원하는 요청에 대해서 허용을 해주면 됩니다.
    2. HTTP OPTION으로 먼저 예비 요청을 보내고, 서버에서 요청을 허용한다는 응답을 받으면 그때 GET or POST로 원하는 리소스 요청을 보내는 방법이다. (생략)
반응형