본문 바로가기

개인적으로 공부한 것을 정리해 놓은 블로그입니다 틀린 것이 있으면 댓글 부탁 드립니다!


Spring Security

스프링시큐리티 공부 1 - 스프링 시큐리티란?

반응형

()웹 사이트는 각종 서비스를 하기 위한 리소스와 서비스를 사용하는 유저들의 개인 정보를 가지고 있다 .이 리소스들을 보호하기 위해서 일반적으로 웹 사이트는 두가지 보안 정책을 설정해야 한다. 스프링에서 이러한 부분들을 서포트 해주는 라이브러리가 스프링 시큐리티이다 .

 

 

인증(Authentication) 

 

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

 

UsernamePassword 인증의 2가지 방식

 - session 관리 

 - 토큰 관리 (sessionless)

 

전통적으로는 session으로 인증을 관리했지만 여러대의 was(scale out)를 사용하게 되면서 session을 분산해서 저장해야 하고  동기화해야 하는 문제 때문에  sessionless 방식인 토큰방식을 이용하는 서비스들이 많이지고 있다. 

 

 

 

인가 혹은 권한 (Authorization)

 

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

 

 

간단한하게 스프링 시큐리티를 살펴보자 

 

프로젝트를 생성하고 스프링 시큐리티를 dependency로 받았다.

 

 

package com.sp.fc.web.controller;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

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

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

 

컨트롤러를 간단하게 만들었다.  

 

auth()를 보면 SecurityContextHolder를 통해 컨텍스트를 얻고 Authentication(인증) 정보를 꺼내고 있다. 

 

브라우저를 통해 해당 경로로 요청해 봤다. 

 

 

 

위와 같은 창이 뜬다 스프링 시큐리티에서 기본적으로 제공하는 로그인창이다 Authentication이 필요한 요청에 해당 로그인창이 뜬다. 현재는 인증이 필요한곳과 필요하지 않은 곳을 따로 분리 해놓지 않았기 떄문에 모든 요청에 대하여 해당 창이 뜬다 .

 

개발시 편의를 위해 username과 password를 application.yml에 임의로 저장해 놓을 수 있다. 

(따로 설정하지 않을 경우 서버가 띄워질 때마다  콘솔창을 확인해보면 비밀번호가 생성되어 제공된다.)

 

server:
  port: 9050
spring:
  security:
    user:
      name: ugo
      password: asdasd1
      roles: USER

 

 

인증 정보를 입력하니 아래와 같은 Json 데이터가 출력됬다. 

 

json fomatter 사이트에서  보기 좋은 형식으로 변환해보자 

 

{
   "authorities":[
      {
         "authority":"ROLE_USER"
      }
   ],
   "details":{
      "remoteAddress":"0:0:0:0:0:0:0:1",
      "sessionId":"C6F734068F2F977D5D8FECB78BFCF458"
   },
   "authenticated":true,
   "principal":{
      "password":null,
      "username":"ugo",
      "authorities":[
         {
            "authority":"ROLE_USER"
         }
      ],
      "accountNonExpired":true,
      "accountNonLocked":true,
      "credentialsNonExpired":true,
      "enabled":true
   },
   "credentials":null,
   "name":"ugo"
}

 

 

아이디 비밀번호 (비밀번호는 왜 null일까) 세션 아이디등 유저의 인증 정보들이 들어있다   

 

만약 user 와 admin role에 따라 접근할 수 있고 없고를 정한다고 생각해보자 

 

 

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

    @PreAuthorize("hasAuthority('ROLE_ADMIN')")
    @RequestMapping("/admin")
    public SecurityMessage admin(){
        return SecurityMessage.builder()
                .auth(SecurityContextHolder.getContext().getAuthentication())
                .message("admin 정보")
                .build();
    }

 

SecurityMessage는 authentication 정보와 간단한 메시지를 담는 DTO이다

 

@PreAuthorzie로 간단하게 해당메서드에 대한 인증을 구현할 수 있다. @PreAuthorize를 사용하기 위해선 

 

스프링에 스프링 시큐리티 관련 설정들을 등록해 줘야한다 .

 

SecurityConfig라는 설정파일을 만들었다 . 

 

package com.sp.fc.web.config;

import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {


}

 

 

스프링 시큐리티 관련 설정을 등록하기 위해선 WebSecurityConfigurerAdapter를 상속 받아야한다 . 

 

@EnableWebSecurity는 WebSecurity관련 기능들을 사용할 수 있게 해주는 어노테이션이고 

@EnableGlobalMethodSecurity(prePostEnabled = true)는 @PreAuthorize와 같이 메소드 레벨에서 인증을 가능하게 해준다 . 옵션으로 prePostEnable(해당 요청 진입시 )로 인증이 가능하도록 설정했다 .

 

서버를 재가동하고 브라우저로 /user /admin 경로로 요청하여 확인해보자 

 

현재 user는 ugo 한명만 등록되어 있고 , Role은 User이기 떄문에 admin에는 접속이 안될 것이다 .

 

 

 

/user로 요청

 

 

/admin으로 요청

 

반응형