SpringBoot with JPA 프로젝트(Security) 1.SpringBoot와 Spring Security 연동 및 Security의 흐름

mingki·2022년 5월 27일
0

SpringBoot & JPA

목록 보기
26/26
post-thumbnail

📚 공부한 책 : 코드로배우는 스프링 부트 웹프로젝트
❤️ github 주소 : https://github.com/qkralswl689/LearnFromCode/tree/main/club

1.시큐리티 설정 클래스 작성

SecurityConfig 클래스는 시큐리티 관련 기능을 쉽게 설정하기 위해 WebSecurityConfigurerAdapter 라는 클래스를 상속처리한다
-> WebSecurityConfigurerAdapter 클래스는 주로 override를 통해 여러 설정을 조정하게 된다
★ 앞으로 모든 시큐리티 관련 설정이 추가되는 부분이다

package com.example.club.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfig  extends WebSecurityConfigurerAdapter {
    
}

2.Controller 작성

시큐리티 관련 설정이 정상적으로 동작하는지 확인하기 위한 컨트롤러를 구성한다

  • 컨트롤러에 사용자의 권한에 따라 접근할 수 있는 경로를 지정한다
package com.example.club.controller;

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

@Controller
@RequestMapping("/sample")
public class SampleController {

    // 로그인을 하지 않은 사용자도 접근 가능
    @GetMapping("/all")
    public void exAll(){
        System.out.println("exALl");
    }

    // 로그인한 사용자만 접근 가능
    @GetMapping("/member")
    public void exMember(){
        System.out.println("exMember");
    }

    // 관리자 권한이 있는 사용자만 접근가능
    @GetMapping("/admin")
    public void exAdmin(){
        System.out.println("exAdmin");
    }
}

3.Thymeleaf 작성

3-1.로그인을 하지 않은 사용자도 접근 가능 한 페이지

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>For All </h1>
</body>
</html>

3-2.로그인한 사용자만 접근 가능한 페이지

<!DOCTYPE html>
<html xmlns:sec="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>For Member ....................</h1>

<div sec:authorize="hasRole('USER')">Has USER ROLE</div>
<div sec:authorize="hasRole('MANAGER')">Has MANAGER ROLE</div>
<div sec:authorize="hasRole('ADMIN')">Has ADMIN ROLE</div>

<div sec:authorize="isAuthenticated()">
    Only Authenticated user can see this Text
</div>

Authenticated username:
<div sec:authentication="name"></div>
Authenticated user roles:
<div sec:authentication="principal.authorities">

</div>

</div>

</body>
</html>

3-2.관리자 권한이 있는 사용자만 접근 가능한 페이지

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>For Admin </h1>
</body>
</html>

4.스프링 시큐리티 용어와 흐름

4.1 스프링시큐리티의 흐름과 핵심역할 및 개념

스프링 시큐리티의 동작에는 여러 개의 객체가 서로 데이터를 주고받으며 이루어진다
-> 스프링 시큐리티의 간단한 흐름

  • 핵심역할 : Authentication Manager(인증 매니저)를 통해 이루어진다, AuthenticationProvider는 인증매니저가 어떻게 동작해야 하는지 결정하고 최종적으로 실제 인증은 UserDetailsService에 의해 이루어진다
  • 핵심개념 : 인증(Authentication) / 인가(Authorization)

4-2. 스프링시큐리티의 필터와 필터체이닝

  • 필터(Filter)는 서블릿이나 JSP에서 사용하는 필터와 같은 개념이다 But 스프링 시큐리티에서는 스프링의 빈과 연동할 수 있는 구조로 설계되어있다.
    -> 일반적인 필터는 스프링의 빈을 사용할 수 없기 때문에 별도의 클래스를 상속받는 형태가 많다
  • 스프링 시큐리티의 내부에는 여러개의 필터가 Filter Chain이라는 구조로 Request를 처리하게 된다
  • 개발 시에 필터를 확장하고 설정하면 스프링 시큐리티를 이용해 다양한 형태의 로그인 처리가 가능하게 된다
  • 스프링 시큐리티의 주요 필터

4-3. 인증을 위한 AuthenticationManager

  • 필터의 핵심적인 동작은 AuthenticationManager를 통해 인증(Authentication)이라는 타입의 객체로 작업하게 된다
  • AuthenticationManager가 가진 인증 처리 메서드는 파라미터도 Authentication 타입으로 받고 리턴 타입 역시 Authentication이다
  • 전달된 ID/PW 로 실제 사용자에 대해 검증하는 행위는 AuthenticationManager(인증 매니저)를 통해 이루어진다
  • 실제 동작에서 전달되는 파라미터는 UsernamePasswordAuthenticationToken과 같이 토큰이라는 이름으로 전달된다
    => 스프링 시큐리티 필터의 주요 역할이 인증 관련된 정보를 토큰이라는 객체로 만들어 전달한다는 의미
  • 예제 코드
String username obtainUsername(request);
username (username! = null) ? username : "";
username username.trim();
String password obtainPassword.(request);
password (password。rd != null) password : "";
UsernamePasswordAuthenthenticationToken authRequest = new
UsernamePasswordAuthenticationToken(username , password) ; 
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);

-> request를 이용해 사용자의 ID/PW를 받아 UsernamePasswordAuthenthenticationToken 이라는 객체를 만들고 이를 AuthenticationManager의 authenticate()에 파라미터로 전달한다. AuthenticationManager는 다양한 방식으로 인증처리 방법을 제공해야 한다.
AuthenticationManager는 이런한 처리를 AuthenticationProvider로 처리한다.
AuthenticationProvider는 전달되는 토큰의 타입을 처리할 수 있는 존재인지 확인하고 이를 통해 authenticate()를 수행하게 된다

  • AuthenticationProvider와 하위 구현 클래스
  • AuthenticationProvider는 내부적으로 UserDetailsService를 이용한다.
    UserDetailsService는 실제로 인증을 위한 데이터를 가져오는 역할을 한다

4-4.인가(Authorization)와 권한/접근제한

  • 인가(Authorization)는 '승인'의 의미이다.
    -> 필터에서 호출하는 AuthenticationManager에는 authenticate()라는 메서드가 있는데 이 메서드의 리턴값은 Authentication이라는 '인증' 정보이다. 이 인증 정보내에는 Roles라는 '권한'에 대한 정보가 있다. 이 정보로 사용자가 원하는 작업을 할수 있는 지 '허가' 하게 되는데 이러한 행위를 'Access-Control(접근 제한)' 이라고 한다.
  • AuthenticationProvider에서 만일 올바른 사용자라고 인증되면 사용자의 정보를 Authentication 타입으로 전달한다. 전달된 객체로 사용자가 적절한 권한이 있는지 확인하는 '인가(Autherization)' 과정을 거치게 된다
profile
비전공초보개발자

0개의 댓글