본문 바로가기
관리자

Programming-[Backend]/Spring Security

[스프링 시큐리티] 10. 프로젝트 생성, PostgreSQL, PasswordEncoder, WebIgnore

728x90
반응형

 

 

1. 프로젝트 생성

 

강의에서 제공하는 소스 코드를 활용하여 처음부터 rebuilding 해본다.

 

 

정수원님 스프링 시큐리티 강의 소스
https://github.com/onjsdnjs/corespringsecurity

 

 

fork 후 내 repository에서 새로운 branch를 따고, 강의를 따라하며 원리를 이해하면 될 것 같다.

 

 

 

PostgreSQL

 

강의에서는 postgreSql을 사용한다. 앱을 실행하려면 application.properties에 DB 연결 정보가 있어야되는데, 강의에서 주어진 코드의 연결정보로는 연결이 어려울 수 있다. 그래서 잠시 postgreSql을 공부해야되는데, 괜찮은 블로그가 참조 2에 있다. 편의를 위해 application.properties 파일은 application.yml 파일로 변경했다.

 

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/데이터베이스명 입력
    username: postgres
    password: 비밀번호 입력

  jpa:
    hibernate:
      ddl-auto: create //나중에는 validate로 입력(jpa 내용)
    properties:
      hibernate:
        format_sql: true
        jdbc:
          lob:
            non_contextual_creation: true

  thymeleaf:
    cache: false

  devtools:
    livereload:
      enabled: true
    restart:
      enabled: true

  main:
    allow-bean-definition-overriding: true

 

postgreql 사용법

은 요약하자면 아래와 같다.(Window 사용자)

 

  1. postgresql.org에 접속해서 설치파일 다운로드 및 설치 -> 패스워드 설정
  2. [윈도우키 + I] 눌러서 시스템 -> 정보 -> 고급 시스템 설정 -> 환경변수 -> 시스템 변수 -> Path 클릭하여 편집 -> postgresql 설치 경로 등록(그냥 설치했다면 C:\Program Files\postgreSQL\14(버전명)\bin)
  3. [윈도우키 + R] 눌러서 실행 -> cmd -> 명령어 입력 psql -U postgres (postgres는 postgresql 설치 시 등록된 기본 super admin 이름) -> 패스워드 입력 후 엔터
  4. "\l"  명령어로 생성되어 있는 데이터 베이스 목록 확인
  5. "CREATE DATABASE 생성할 데이터베이스 이름;" 명령어로 데이터 베이스 생성
  6. 추가로 필요하다면 아래 사진과 같이 intelliJ에서 데이터베이스 확인

 

 

 


 

2.기본 환경 설정

 

 

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        String password = passwordEncoder().encode("1111");

        auth.inMemoryAuthentication().withUser("user").password(password).roles("USER");
        auth.inMemoryAuthentication().withUser("manager").password(password).roles("MANAGER");
        auth.inMemoryAuthentication().withUser("admin").password(password).roles("ADMIN");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/mypage").hasRole("USER")
                .antMatchers("/manager").hasRole("MANAGER")
                .antMatchers("/admin").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin();

    }
}

 

기본적인 내용은 이전에 배운 바와 같다. user, manager, admin 이라는 유저를 생성하고 configure(AuthenticationManagerBuilder auth) 메서드를 통해서 username, password를 설정한다. 이렇게 설정하면 .antMatchers에 따라서 자원과 권한에 따라 접근 여부가 결정된다.

 

PasswordEncoder

다만 여기서는 PasswordEncoder를 추가로 도입한다. 입력한 패스워드를 자동으로 해싱처리해주는 기능인데, @Bean으로 불러와야 하고 위 코드와 같이 factories를 불러와서 사용해야 한다.

 

factories는 아래와 같이 암호화할 수 있는 해싱 타입을 지원한다.

public class PasswordEncoderFactories {
    public static PasswordEncoder createDelegatingPasswordEncoder() {
        String encodingId = "bcrypt";
        Map<String, PasswordEncoder> encoders = new HashMap();
        encoders.put(encodingId, new BCryptPasswordEncoder());
        encoders.put("ldap", new LdapShaPasswordEncoder());
        encoders.put("MD4", new Md4PasswordEncoder());
        encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
        encoders.put("noop", NoOpPasswordEncoder.getInstance());
        encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
        encoders.put("scrypt", new SCryptPasswordEncoder());
        encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
        encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
        encoders.put("sha256", new StandardPasswordEncoder());
        encoders.put("argon2", new Argon2PasswordEncoder());
        return new DelegatingPasswordEncoder(encodingId, encoders);
    }

    private PasswordEncoderFactories() {
    }
}

 

그리고 인터페이스인 PasswordEncoder는 encode, matches 메서드를 지원하여 해싱 및 password 일치 여부를 반환해준다.

 

public interface PasswordEncoder {
    String encode(CharSequence var1);

    boolean matches(CharSequence var1, String var2);

    default boolean upgradeEncoding(String encodedPassword) {
        return false;
    }
}

 

 


 

3. WebIgnore

 

WebIgnore를 이용해서 js/css/image 파일 등 보안 필터가 필요없는 리소스를 지정할 수 있다. 설정 시 이런 파일들은 보안 필터를 거치지 않게 된다.

 

아래 코드를 따라서 들어가보면, enum 타입으로 보안 필터를 거치지 않는 리소스를 지정하는 것을 확인할 수 있다.

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}

위와 같이 configure(WebSecurity web) 메서드를 Override 해주면 된다. 

 

.atCommonLocations()

public StaticResourceRequest.StaticResourceRequestMatcher atCommonLocations() {
    return this.at(EnumSet.allOf(StaticResourceLocation.class));
}

 

StaticResourceLocation.class

public enum StaticResourceLocation {
    CSS(new String[]{"/css/**"}),
    JAVA_SCRIPT(new String[]{"/js/**"}),
    IMAGES(new String[]{"/images/**"}),
    WEB_JARS(new String[]{"/webjars/**"}),
    FAVICON(new String[]{"/**/favicon.ico"});

    private final String[] patterns;

    private StaticResourceLocation(String... patterns) {
        this.patterns = patterns;
    }

    public Stream<String> getPatterns() {
        return Arrays.stream(this.patterns);
    }
}

 

.permitAll()은 일단 필터는 거치지만 필터에서 자원들을 해석하여 통과 여부를 결정하지만, webIgnore 같은 경우 정말 filter 자체를 거치지 않는 차이가 있다.

 

 

 


 

참조

 

1) 인프런 - 스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - 정수원님 강의

https://www.inflearn.com/course/%EC%BD%94%EC%96%B4-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0

 

2) PostgreSql 설명 블로그

http://www.devkuma.com/books/pages/1425

728x90
반응형