Learn/KH정보교육원

[정보교육원 당산] 83일( Spring boot - Security )

Dahoon06 2021. 7. 19. 14:02
728x90
반응형

Security

: Spring Security는 스프링 기반의 어플리케이션 보안을 담당하는 프레임워크입니다.

Spring Security를 사용하면 사용자 인증, 권한, 보안처리를 간단하게 구현할 수 있다.

 

인증(Authentication) : 사용자 식별

예) 사원이 회사 건물 들어가기 위해 사원증, RFID 카드를 이용하여 반드시 인증을 통과.

 

인가(Authorization) : 시스템 자원에 대한 접근 통제

예) 직급, 직무에 따라 부여된 권한이 다르기 때문에 회사내에서 열람할 수 있는 문서의 종류도 제한.

직원이 특정 자원에 접근할 때 적적한 권한이 있는지를 확인하는 과정

 

Spring Security는 기본적으로 인증 절차를 거친 후에 인가 절차를 진행하게 되며, 인가 과젱에서 해당 리소스에 대한 접근 권한이 있는지 확인을 하게 된다. Spring Security에서는 이러한 인증과 인가를 위해 Principal을 아이디로, Credential을 비밀번호로 사용하는 Credential 기반의 인증 방식을 사용한다.

  • Principal(접근 주체): 보호받는 Resource에 접근하는 대상
  • Credential(비밀번호): Resource에 접근하는 대상의 비밀번호

 

기존. 세선(HttpSession)을 기반으로 로그인에 성공한 사용자만 글등록, 목록, 검색 등을 하였다면,

스프링에서는 스프링 시큐리티를 쉽게 사용할 수 있도록 시큐리티 스타터를 제공한다.

따라서, 스타터를 프로젝트에 적용하면 시큐리티 관련 의존성, 복잡한 시큐리티 설정들을 자동으로 처리해준다.

 

 


 

스프링 부트 프로젝트 생성 후

디펜던시를 걸어 줄때 security 에서 spring security 선택

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

 

테스트를 위한 hello.html을 static 디렉토리에 생성 후에 

 

서버 실행 후 해당 html 호출

 

***  처음 디펜던시를 걸때 Oracle 드라이버를 선택하여 라이브러리를 다운 받았었다.

그런 후에 프로젝트를 구동하게 되면 데이터베이스 설정을 하지 않아서 구동이 되지 않는다.

@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class SpringSecurityApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringSecurityApplication.class, args);
	}

}

~~Application 쪽에 @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

어노테이션을 추가해 주면 데이터베이스 설정을 하지 않아도 서버를 구동시킬 수 있다.

 

 

서버를 구동시킨후에 hello.html을 실행시키게 되면

url이 login으로 바뀌면서 인증 화면이 나오게 된다.

 

application.propertiest 에 계정과 패스워드 정보추가

spring.security.user.name=user
spring.security.user.password=test123

만약 계정 정보를 바꿔주지 않는다면

기본 계정값 : user

기본 비밀번호 : security password 로 설정 되어있다.

 

인증에 실패한다면 아래와 같은 이미지가 뜨고

성공한다면 hello.html화면이 나오게된다.

 

스프링 부트는 기본적으로 INFO레벨 이상의 로그 값만 출력하도록 기본 설정 되어 있는데,

만약 시큐리티와 관련된 로그까지 확인하기 위해서는

application.properties 파일에 시큐리티 관련 로그를 debug로 설정해야한다.

logging.level.org.springframework.security=debug

 

** Log4j Level 설정 (6단계로 구분되어있다.)

ALL – The ALL has the lowest possible rank and is intended to turn on all logging.
=> 모든 로깅.


TRACE – The TRACE Level designates finer-grained informational events than the DEBUG
=> 세밀
DEBUG – The DEBUG Level designates fine-grained informational events that are most useful to debug an application.
=> 디버깅.
INFO – The INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
=> 강조 정보.
WARN – The WARN level designates potentially harmful situations.
=> 경고.
ERROR – The ERROR level designates error events that might still allow the application to continue running.
=> 오류.
FATAL – The FATAL level designates very severe error events that will presumably lead the application to abort.
=> 심각한 오류.


OFF – The OFF has the highest possible rank and is intended to turn off logging.
=> 로깅 해제.

 

 


Security Customizing (시큐리티 설정 파일)

confing 패키지 추가 -> SecurityConfing.java 생성

 

SecurityConfig는 WebSecurityConfigurerAdapter를 상속

WebSecurityConfigurerAdapter => 다양한 설정을 추가할 수 있는 configure() 메서드 보유

SecurityConfig에서 해당 메서드를 재정의함으로써 시큐리티 설정을 바꿀 수 있다.

 

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfiguration {

	public SecurityConfig() {
	}

}

 

 

configure()는 HttpSecurity 객체를 매개변수로 전달받는데, HttpSecurity객체를 이용하여 애플리케이션 자원에 대한 인증과 인가를 제어할 수 있다.

 

SecurityConfig에 @EnableWebSecurity 어노테이션 부여

=> 이 클래스로부터 생성된 객체는 시큐리티 설정파일임을 나타내는 어노테이션(또한, 시큐리티 사용에 필요한 객체들을 생성한다.)

 

package com.jdh.Spring_security.config;



import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	public SecurityConfig() {
	}

	@Override
	protected void configure(HttpSecurity security) throws Exception {
		//매개 변수 security를 통해 전달받은 HttpSecurity 객체를 이용하여 인증, 인가를 제어
		security.authorizeRequests().antMatchers("/").permitAll();
		
		security.authorizeRequests().antMatchers("/member/**").authenticated(); // 인증된
		security.authorizeRequests().antMatchers("/manager/**").hasRole("MANAGER");// 인가하기 위한 규칙
		security.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN");
		
		//크로스 사이트 위조 요청에 대한 설정
		// : csrf() ->     disable()
		security.csrf().disable(); // RestFULL 을 사용하기 위해서는 CSRF 기능을 비활성화 해야한다.
		//로그인 성공시에 어디로 이동하라는 지시
        security.formLogin().loginPage("/login").defaultSuccessUrl("/loginsuccess", true);
        
        //로그아웃
        security.logout().invalidateHttpSession(true).logoutSuccessUrl("/home");
	
	}

}
 * 크로스 사이트 요청 위조 방지
1. 이름 : CSRF (Cross Site Request Forgery)
2. 내용 : 요청이 발생했을 때, 서버에서 요청에 대한 주체와 요청 절차에 대한 검증을 하지 않고 
           요청을 처리했을 경우 발생

-----------------------------------------------------

RESTfull

REST : 자원을 이름으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미     
         자원 : 넒은 의미로 소프트웨어가 관리하는 모든 것 (그림, 문서, 데이터 등)
                 DB에 학생 정보가 저장되어 있을 경우, 이 학생들의 정보가 자원.

일반적인 REST
좁은 의미로 http 를 통하여 CRUD를 실행하는 API.
http 프로토콜을 이용하기 때문에 URI(route)를 통해 자원을 표시하고,
http 메서드들을 통해 할 일(CRUD)을 처리하도록 설계된 아키텍쳐

RESTfull : 일반적으로 REST라는 아키텍처를 구현하는 웹서비스를 나타내기 위해 사용되는 용어.
REST API를 제공하는 웹 서비스를 RESTful 하다고 할 수 있다.,


RESTful 하지 못한 예
=> CRUD 기능을 모두 POST로만 처리하는 API
=> Route에 resurce, id 와 정보가 들어가는 경우
		 * **/

 

1. 특정 경로에 대한 권한을 가진 사용자만 접근을 허용할 경우, AuthorizedUrl 객체의 메서드를 이용
  AuthorizedUrl은 HttpSecurity의 authorizeRequests()를 호출할 때 리턴되는 
  EspressionInterceptUrlRegistry의 antMatchers() 메서드를 통해 얻어낸다.
 
  authorizeRequests() : 사용자 인증,권한 설정
  antMatchers("url패턴) : 매칭되는 url패턴들에 대한 권한 설정 
  permitAll => 모든 사용자에 대한 접근 허용
  hasRole("권한이름") => 특정 권한을 가진 사람만 접근 허용
 
  2. 모든 사용자에게 접근 권한을 부여할 경우 : AuthorizedUrl의 permitAll()를 이용하여 접근 허가
 
  3. 필요한 메서드 => formLogin() : 로그인(인증) 페이지 설정
  : loginPage("URL 패턴") 메서드

    defaultSuccessUrl("URL 패턴", true);

** 인증되지 않은 사용자가 시스템에 접근할 경우, 브라우저는 /login을 요청을 리다이렉트하여

인증을 받을 수 있게 한다. 

그렇기 때문에 해당 URL 요청을 받을 수 있는 컨트롤러 필요("/login", "/loginSuccess") 
 

 


 * logout() : 로그아웃 페이지 설정

스프링 시큐리티의 인증 방식은 기본적으로 HttpSession을 이용한다.

따라서 브라우저가 종료되면 해당 세션도 종료된다.

만약 브라우저를 종료하지 않고, 세션을 종료하려면 사용자가 로그아웃을 요청하여 세션을 종료시킨다.

=> invalidateHttpSession(true);

: 현재의 브라우저와 관련된 모든 세션을 강제 종료시킨다.

=> logoutSuccessUrl("URL패턴"); 

: 로그아웃이 끝나면 이동할 URL

 

 

*** 에러 페이지 설정

security.exceptionHandling().accessDeniedPage("/error");

이와같이 직접 설정할 수 도 있다, 주의할 점은 URL 패턴을 추가했으므로 반드시 컨트롤러에서도 해당 URL을 추가해야한다.

 

 

URL => "/" : 인증하지 않는 모든 사용자가 접근가능

           "/member" : 인증을 통과한 사용자만 접근가능

           "/mamager" : 인증을 통과했고, Manager 권한을 가진 사용자만 접근가능

           "/admin" : 인증을 통과했고, Admin 권한을 가진 사용자만 접근가능

 

** 해당 URL로 접근을 할 수 있도록 컨트롤러 생성

 

package com.jdh.Spring_security.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SecurityController {

	public SecurityController() {
	}
	
	@GetMapping("/")
	public String index(){
		return "index";
	}
	
	@GetMapping("/member")
	public void forMember(){
	}
	
	@GetMapping("/manager")
	public void forManager(){
	}
	
	@GetMapping("/admin")
	public void forAdmin(){
	}
	
	@GetMapping("/login")
	public void login(){
	}
	
	@GetMapping("/loginSuccess")
	public void loginSuccess(){
	}
}

 

 


728x90
반응형