backend
  • README
  • DOCS
    • Java Docs
    • Servlet Docs
    • JSP Docs
    • DB & SQL Docs
    • Spring Boot Docs
    • Spring Security Docs
    • AWS Docs
  • 설치하기
    • Intellij 설정
  • 자바
    • 01 Java란?
    • 02 자바 시작하기
    • 03 자료형과 연산자
    • 04 제어문
    • 05 메소드
    • 06 클래스 기초
      • Static 보충자료
      • 패키지 보충자료
    • 07 객체지향 프로그래밍
    • 08 클래스 더 알아보기
      • 열거형 ENUM 보충자료
    • 09 클래스와 자료형
      • 다형성 보충자료
      • 제네릭 보충자료
    • 10 컬렉션 프레임워크
      • 컬렉션 프레임워크 보충자료
    • 11 람다식과 함수형 프로그래밍
      • 람다식 보충자료
    • 12 오류 대비하기
      • 오류 보충자료
    • 13 멀티태스킹
      • 멀티태스킹 보충자료
    • 교재보충
      • java.lang
  • 스프링
    • 서블릿, JSP
      • 05 Servlet(서블릿)
        • 서블릿 보충자료
        • 서블릿 추가코드
        • XML, YAML, JSON
      • 06 JSP(자바 서버 페이지)
        • JSP 보충자료
      • 07 JSTL(JSP 스탠다드 태그 라이브러리)
        • JSTL 보충자료
      • 08 Cookie(쿠키), Session(세션)
      • 09 서블릿,필터,리스너
        • 서블릿,필터,리스너 보충자료
      • 11 도서관리 프로젝트 실습
    • Spring Boot
      • 01 스프링 등장 배경, 객체지향
        • 스프링 등장 배경, 객체지향 보충자료
      • 02 IOC(제어의 역전), DI(의존성 주입)
        • IOC 보충자료
        • DI 보충자료
      • 03 스프링 구조
        • 스프링 구조 보충설명
      • 04 테스트코드 실습
      • 05 스프링 빈 설정
        • 스프링 빈 설정 보충자료
      • 06 싱글톤
        • 싱글톤 보충 자료
      • 07 스프링 빈 자동설정
        • 스프링 빈 자동설정 보충자료
      • 08 빈 생명주기
        • 빈 생명주기 보충자료
      • 09 빈 스코프
        • 빈 스코프 보충자료
      • 10 스프링 MVC
        • 스프링 MVC 보충자료
        • 데이터베이스 연동에 필요한 부분
      • 11 Validation(검증)
        • Validation(검증) 보충자료
      • 12 Bean Validation(빈검증)
        • Bean Validation(빈검증) 보충자료
      • 13 예외처리
        • 예외처리 보충자료
      • 14 타입변환
      • 15 JDBC(Java Database Connectivity)
      • 16 커넥션풀
      • 17 트랜잭션
        • 트랜잭션 보충자료
      • 18 JDBC 템플릿 활용
      • 19 MyBatis
      • 20 JPA(Java Persistence API)
      • 22 게시판 프로젝트 실습
    • Spring Security
      • 보안(Security)
      • Spring Security
      • 2. Spring Security 알아보기
        • 보안 위협 실제 사례와 방어 전략
      • 3. Spring Security 기본 동작 흐름
      • 4. Spring Security로 인증 권한 추가하기
        • Spring Security의 인증 및 인가
      • 5. Spring Security에서 세션 관리하기
        • 세션(Session)과 쿠키(Cookie) 비교, 토큰(Token)과의 관계
        • 해싱 및 해싱알고리즘
        • base64
      • 6. Spring Security 악용 보호
        • SameSite
      • 7. Spring Security로 인가 권한 추가하기
      • 8. Bcrypt(비크립트) 암호화
      • OAuth2 적용하기
  • 네트워크
    • HTTP
    • OSI 7계층
  • DB&SQL
    • 01 Database(데이터베이스)와 SQL 개요
    • 02 관계형 모델
    • 03 집합
    • 04 JOIN 연산
    • 05 MySQL
      • 세이브포인트
      • DBeaver, Mysql 오토커밋 설정 관련
    • 06 SQL 기초
      • 예시데이터 쿼리문
    • 07 SQL 실습
      • 실습 스키마
    • 08 Join 활용
      • 실습스키마
    • 09 SQL 활용
      • 실습스키마
    • 10 정규화
      • 실습 스키마
    • 데이터타입
    • 예시 프로젝트 스키마 구성
  • AWS
    • SSL 연결하기
    • 보충설명
Powered by GitBook
On this page
  1. 스프링
  2. Spring Security

4. Spring Security로 인증 권한 추가하기

p35 - p38

SecurityConfig2.java

package io.securitylecture.springsecuritylecture.config;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.IOException;

@EnableWebSecurity
@Configuration
public class SecurityConfig2 {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .formLogin(Customizer.withDefaults());

        return http.build();
    }
}

p39

SecurityConfig2.java

package io.securitylecture.springsecuritylecture.config;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.IOException;

@EnableWebSecurity
@Configuration
public class SecurityConfig2 {

//    @Bean
//    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
//        http
//                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
//                .formLogin(Customizer.withDefaults());
//
//        return http.build();
//    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .formLogin(form -> {
                            form
//                                    .loginPage("/loginPage")
                                    .loginProcessingUrl("/loginProc")
                                    .defaultSuccessUrl("/", true)
                                    .failureUrl("/failed")
                                    .usernameParameter("userId")
                                    .passwordParameter("passwd")
                                    //실제 내부 객체
//                                    .successHandler(new AuthenticationSuccessHandler() {
//                                        @Override
//                                        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//
//                                        }
//                                    })
                                    //람다형태로 변경
                                    .successHandler((request, response, authentication) -> {
                                        System.out.println("authentication : " + authentication);
                                        response.sendRedirect("/home");
                                    })
                                    .failureHandler((request, response, exception) -> {
                                        System.out.println("exception: " + exception.getMessage());
                                        response.sendRedirect("/login");
                                    })
                                    .permitAll();
                        }

                );

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails user = User.withUsername("user")
                .password("{noop}111")
                .roles("USER").build();
        return new InMemoryUserDetailsManager(user);
    }
}

controller/IndexController

package io.securitylecture.springsecuritylecture.controller;

import org.springframework.security.core.Authentication;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.annotation.CurrentSecurityContext;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {

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

    @GetMapping("home")
    public String home() {
        return "home";
    }

    @GetMapping("loginPage")
    public String loginPage() {
        return "loginPage";
    }

    @GetMapping("anonymous")
    public String anonymous() {
        return "anonymous";
    }

    @GetMapping("authentication")
    public String authentication(Authentication authentication) {
        if (authentication instanceof AnonymousAuthenticationToken) {
            return "anonymous";
        } else {
            return "not anonymous";
        }
    }

    @GetMapping("/anonymousContext")
    public String anonymousContext(@CurrentSecurityContext SecurityContext context){
        return context.getAuthentication().getName();
    }

    @GetMapping("logoutSuccess")
    public String logoutSuccess() {
        return "logoutSuccess";
    }

    @GetMapping("invalidSessionUrl")
    public String invalidSessionUrl() {
        return "invalidSessionUrl";
    }

    @GetMapping("expiredUrl")
    public String expiredUrl() {
        return "expiredUrl";
    }

    @GetMapping("hello")
    public String sayHello() {
        return "Hello, CORS and CSRF Test!";
    }

    // CSRF 토큰을 확인하는 엔드포인트
    @GetMapping("/csrf-token")
    public String getCsrfToken(CsrfToken csrfToken) {
        return "CSRF Token: " + csrfToken.getToken();
    }

    // CSRF 보호가 적용된 POST 요청 엔드포인트
    @PostMapping("/submit-csrf")
    public String submitWithCsrf() {
        return "Form submitted successfully with CSRF protection!";
    }
}

p50

SecurityConfig3

package io.securitylecture.springsecuritylecture.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
@Configuration
public class SecurityConfig3 {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .httpBasic(Customizer.withDefaults());
        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails user = User.withUsername("user")
                .password("{noop}111")
                .roles("USER").build();
        return new InMemoryUserDetailsManager(user);
    }
}

p64

SecurityConfig4.java

package io.securitylecture.springsecuritylecture.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
@Configuration
public class SecurityConfig4 {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
                .formLogin(Customizer.withDefaults())
                .rememberMe(rememberMe -> rememberMe
//                        .alwaysRemember(true) // '기억하기' 매개변수가 설정되지 않아도 쿠키가 항상 생성됨
                        .tokenValiditySeconds(3600) //초단위, 한시간
                        .userDetailsService(userDetailsService()) // UserDetailsService를 통해 사용자 정보를 조회함
                        .rememberMeParameter("remember") // 로그인 폼에서 Remember Me를 선택할 때 사용하는 매개변수 이름 설정
                        .rememberMeCookieName("remember") // Remember Me 쿠키의 이름을 설정 (기본값은 'remember-me')
                        .key("security") // Remember Me 토큰을 생성할 때 사용할 키 (토큰의 무결성을 보장)
                );

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails user = User.withUsername("user")
                .password("{noop}111")
                .roles("USER").build();
        return new InMemoryUserDetailsManager(user);
    }
}

p71

SecurityConfig5.java

package io.securitylecture.springsecuritylecture.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@EnableWebSecurity
@Configuration
public class SecurityConfig5 {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/anonymous").hasRole("GUEST") // "/anonymous" 경로에 GUEST 역할을 가진 사용자만 접근 허용
                        .requestMatchers("/authentication","/anonymousContext").permitAll()
                        .anyRequest().authenticated()) // 그 외 모든 요청은 인증된 사용자만 허용
                .formLogin(Customizer.withDefaults()) // 기본 폼 로그인 사용
                .anonymous(anonymous -> anonymous
                        .principal("guest") // 익명 사용자의 주체를 "guest"로 설정
                        .authorities("ROLE_GUEST") // 익명 사용자에게 "ROLE_GUEST" 권한 부여
                        )
                ;

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails user = User.withUsername("user")
                .password("{noop}111")
                .roles("USER").build();
        return new InMemoryUserDetailsManager(user);
    }
}

p74

SecurityConfig6.java

package io.securitylecture.springsecuritylecture.config;

import jakarta.servlet.http.HttpSession;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@EnableWebSecurity
@Configuration
public class SecurityConfig6 {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/logoutSuccess").permitAll()
                        .anyRequest().authenticated())
                .formLogin(Customizer.withDefaults()) // 기본 폼 로그인 사용
                .logout(logout -> logout
                        .logoutUrl("/logout")  // 로그아웃이 발생할 URL 설정
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))  // 로그아웃 요청 처리 방식과 URL 설정
                        .logoutSuccessUrl("/logoutSuccess")  // 로그아웃 성공 후 이동할 URL 설정
                        .logoutSuccessHandler((request, response, authentication) -> {
                            response.sendRedirect("/logoutSuccess");  // 로그아웃 후 처리 동작 설정
                        })
                        .deleteCookies("JSESSIONID", "CUSTOM_COOKIE", "remember-me")  // 로그아웃 시 삭제할 쿠키 설정
                        .invalidateHttpSession(true)  // 세션 무효화 설정
                        .clearAuthentication(true)  // 인증 정보 삭제 설정
                        .addLogoutHandler((request, response, authentication) -> {
                            // 추가 로그아웃 처리 작업 가능
                            HttpSession session =  request.getSession();
                            session.invalidate();  //현재 사용자의 세션 무효화
                            SecurityContextHolder.getContextHolderStrategy().getContext().setAuthentication(null); //현재 인증 정보를 null로 설정
                            SecurityContextHolder.getContextHolderStrategy().clearContext(); //SecurityContext에서 모든 인증 정보를 제거하여, 로그아웃된 상태로 설정
                        })
                        .permitAll()  // 모든 사용자가 로그아웃 URL에 접근할 수 있도록 설정
                );

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails user = User.withUsername("user")
                .password("{noop}111")
                .roles("USER").build();
        return new InMemoryUserDetailsManager(user);
    }
}
Previous3. Spring Security 기본 동작 흐름NextSpring Security의 인증 및 인가

Last updated 3 months ago