[Spring] Spring Security(2)

99winnmin·2022년 7월 26일
0

Spring

목록 보기
15/17

스프링 시큐리티란?

웹사이트는 각종 서비스를 하기 위한 리소스와 서비스를 사용하는 유저들의 개인 정보를 가지고 있는데 이들 리소스를 보호하기 위해서 일반적으로 웹 사이트는 두가지 보안 정책이 요구된다.

  • 서버 리소스
  • 유저들의 개인정보

인증(Authentication)

사이트에 접근하는 사람이 누구인지 시스템이 알아야 한다. 익명사용자(anonymous user)를 허용하는 경우도 있지만, 특정 리소스에 접근하거나 개인화된 사용성을 보장 받기 위해서는 반드시 로그인하는 과정이 필요하다. 로그인은 보통 username / password 를 입력하고 로그인하는 경우와 sns 사이트를 통해 인증을 대리하는 경우가 있습니다.

  • UsernamePassword 인증
    • Session 관리
    • 토큰 관리 (sessionless)
  • Sns 로그인 (소셜 로그인) : 인증 위임

권한(Authorization)

사용자가 누구인지 알았다면 사이트 관리자 혹은 시스템은 로그인한 사용자가 어떤 일을 할 수 있는지 권한을 설정해야한다. 권한은 특정 페이지에 접근하거나 특정 리소스에 접근할 수 있는 권한여부를 판단하는데 사용된다. 개발자는 권한이 있는 사용자에게만 페이지나 리소스 접근을 허용하도록 코딩해야 하는데, 이런 코드를 쉽게 작성할 수 있도록 프레임워크를 제공하는 것이 스프링 시큐리티 프레임워크(Spring Security Framework)이다.

  • annotation으로 체크하는 방식
    • Secured : deprecated
    • PrePostAuthorize
  • 비지니스 형식
    • AOP

간단한 권한 체크 해보기

일반유저 vs admin유저

  • HomeController.java
@RestController
public class HomeController {

    @RequestMapping("/")
    public String index(){
        return "index";
    }

    @RequestMapping("/auth")
    public Authentication auth(){
        return SecurityContextHolder.getContext()
                .getAuthentication();
    }

    @PreAuthorize("hasAnyAuthority('ROLE_USER')")
    @RequestMapping("/user")
    public SecurityMessage user(){
        return SecurityMessage.builder()
                .auth(SecurityContextHolder.getContext().getAuthentication())
                .message("User 정보")
                .build();
    }

    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')")
    @RequestMapping("/admin")
    public SecurityMessage admin(){
        return SecurityMessage.builder()
                .auth(SecurityContextHolder.getContext().getAuthentication())
                .message("admin 정보")
                .build();
    }
}
  • SecurityConfig.java
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true) // prePost로 권한 체크를 하겠다
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication() // 해당 설정을 하게되면 .yaml의 user는 더이상 접속 불가
                .withUser(User.builder()
                        .username("user2")
                        .password(passwordEncoder().encode("2222"))
                        .roles("USER")
                )
                .withUser(User.builder()
                        .username("admin")
                        .password(passwordEncoder().encode("3333"))
                        .roles("ADMIN")
                );
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 기본 설정은 무조건 권한을 요구하게 되어있지만 홈페이지는 권한이 필요없게 설정함
        http.authorizeRequests((requests) ->
                requests.antMatchers("/").permitAll()
                        .anyRequest().authenticated());
        http.formLogin();
        http.httpBasic();
    }
}

그러나 WebSecurityConfigurerAdapter는 곧 없어질 API기 때문에 다른 방법을 강구해야함

메모리 사용자 인증

간단히 특정된 소스를 위한 서비스나 테스트를 위해 사용하는 용도로 사용합니다. 스프링 시큐리티를 테스트 하기 위한 용도로 사용합니다.

  • 기본 사용자 로그인
  • application.yml 에 설정하고 로그인하기
  • UserDetailService 를 이용하기
  • WebSecurityConfigurerAdapter 를 사용하기
profile
功在不舍

0개의 댓글