[SpringBoot] 스프링부트 프로젝트 생성 후 spring-security 사용 및 테스트하기1 login 설정~로그인 설정~(세팅 스프링 시큐리티 세션 스프링부트3.25 )_IntelliJ IDEA 2024.1JDK17 spring-boot test session http--++

* 초기 세팅 (개발환경) 및 설정 

https://rockbottomdevbus.blogspot.com/2024/04/springboot-1-325-intellij-idea-20241.html


* 라이브러리 추가

- build.gradle 수정  

-- build.gradle

//스프링 시큐리티
implementation 'org.springframework.boot:spring-boot-starter-security'


1. 라이브러리 빌드 후 실행 및 로그 확인 

- 실행 >> 인텔리제이 콘솔 로그확인 

- ID / PW 확인 : 주의! 패스워드는 실행될 때 마다 바뀜

- 16개의 필터가 확인됨 


Using generated security password: de1c3259-32f8-41de-9ba3-e244ea0ce779

This generated password is for development use only. Your security configuration must be updated before running your application in production.


2024-05-03T12:28:40.126+09:00  INFO 996 --- [b01] [  restartedMain] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@9a71690, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@728ba0c4, org.springframework.security.web.context.SecurityContextHolderFilter@7d3776cf, org.springframework.security.web.header.HeaderWriterFilter@26fbc530, org.springframework.web.filter.CorsFilter@2291233e, org.springframework.security.web.csrf.CsrfFilter@344f3802, org.springframework.security.web.authentication.logout.LogoutFilter@229b9149, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@27133775, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@13ef0230, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@70f8dcc2, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@40d76000, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@70b63923, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@456d1fa, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@41da47db, org.springframework.security.web.access.ExceptionTranslationFilter@4fce7cbe, org.springframework.security.web.access.intercept.AuthorizationFilter@d17c727]

2024-05-03T12:28:40.184+09:00  INFO 996 --- [b01] [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729

2024-05-03T12:28:40.235+09:00  INFO 996 --- [b01] [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8090 (http) with context path ''

2024-05-03T12:28:40.251+09:00  INFO 996 --- [b01] [  restartedMain] org.zerock.b01.B01Application            : Started B01Application in 6.925 seconds (process running for 7.682)

2024-05-03T12:28:58.843+09:00  INFO 996 --- [b01] [nio-8090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'

2024-05-03T12:28:58.843+09:00  INFO 996 --- [b01] [nio-8090-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'

2024-05-03T12:28:58.845+09:00  INFO 996 --- [b01] [nio-8090-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms

2024-05-03T12:28:58.881+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@9a71690, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@728ba0c4, org.springframework.security.web.context.SecurityContextHolderFilter@7d3776cf, org.springframework.security.web.header.HeaderWriterFilter@26fbc530, org.springframework.web.filter.CorsFilter@2291233e, org.springframework.security.web.csrf.CsrfFilter@344f3802, org.springframework.security.web.authentication.logout.LogoutFilter@229b9149, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@27133775, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@13ef0230, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@70f8dcc2, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@40d76000, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@70b63923, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@456d1fa, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@41da47db, org.springframework.security.web.access.ExceptionTranslationFilter@4fce7cbe, org.springframework.security.web.access.intercept.AuthorizationFilter@d17c727]] (1/1)

2024-05-03T12:28:58.881+09:00 DEBUG 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /login

2024-05-03T12:28:58.882+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking DisableEncodeUrlFilter (1/16)

2024-05-03T12:28:58.883+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking WebAsyncManagerIntegrationFilter (2/16)

2024-05-03T12:28:58.885+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking SecurityContextHolderFilter (3/16)

2024-05-03T12:28:58.887+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking HeaderWriterFilter (4/16)

2024-05-03T12:28:58.889+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking CorsFilter (5/16)

2024-05-03T12:28:58.889+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking CsrfFilter (6/16)

2024-05-03T12:28:58.891+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.csrf.CsrfFilter         : Did not protect against CSRF since request did not match CsrfNotRequired [TRACE, HEAD, GET, OPTIONS]

2024-05-03T12:28:58.892+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking LogoutFilter (7/16)

2024-05-03T12:28:58.892+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.s.w.a.logout.LogoutFilter            : Did not match request to Ant [pattern='/logout', POST]

2024-05-03T12:28:58.892+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking UsernamePasswordAuthenticationFilter (8/16)

2024-05-03T12:28:58.892+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] w.a.UsernamePasswordAuthenticationFilter : Did not match request to Ant [pattern='/login', POST]

2024-05-03T12:28:58.892+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.security.web.FilterChainProxy        : Invoking DefaultLoginPageGeneratingFilter (9/16)

2024-05-03T12:28:58.895+09:00 TRACE 996 --- [b01] [nio-8090-exec-1] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match request to [Is Secure]

2024-05-03T12:28:58.975+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Trying to match request against DefaultSecurityFilterChain [RequestMatcher=any request, Filters=[org.springframework.security.web.session.DisableEncodeUrlFilter@9a71690, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@728ba0c4, org.springframework.security.web.context.SecurityContextHolderFilter@7d3776cf, org.springframework.security.web.header.HeaderWriterFilter@26fbc530, org.springframework.web.filter.CorsFilter@2291233e, org.springframework.security.web.csrf.CsrfFilter@344f3802, org.springframework.security.web.authentication.logout.LogoutFilter@229b9149, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@27133775, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@13ef0230, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@70f8dcc2, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@40d76000, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@70b63923, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@456d1fa, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@41da47db, org.springframework.security.web.access.ExceptionTranslationFilter@4fce7cbe, org.springframework.security.web.access.intercept.AuthorizationFilter@d17c727]] (1/1)

2024-05-03T12:28:58.975+09:00 DEBUG 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Securing GET /favicon.ico

2024-05-03T12:28:58.975+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking DisableEncodeUrlFilter (1/16)

2024-05-03T12:28:58.975+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking WebAsyncManagerIntegrationFilter (2/16)

2024-05-03T12:28:58.975+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking SecurityContextHolderFilter (3/16)

2024-05-03T12:28:58.975+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking HeaderWriterFilter (4/16)

2024-05-03T12:28:58.975+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking CorsFilter (5/16)

2024-05-03T12:28:58.975+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking CsrfFilter (6/16)

2024-05-03T12:28:58.975+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.csrf.CsrfFilter         : Did not protect against CSRF since request did not match CsrfNotRequired [TRACE, HEAD, GET, OPTIONS]

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking LogoutFilter (7/16)

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.s.w.a.logout.LogoutFilter            : Did not match request to Ant [pattern='/logout', POST]

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking UsernamePasswordAuthenticationFilter (8/16)

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] w.a.UsernamePasswordAuthenticationFilter : Did not match request to Ant [pattern='/login', POST]

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking DefaultLoginPageGeneratingFilter (9/16)

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking DefaultLogoutPageGeneratingFilter (10/16)

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] .w.a.u.DefaultLogoutPageGeneratingFilter : Did not render default logout page since request did not match [Ant [pattern='/logout', GET]]

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking BasicAuthenticationFilter (11/16)

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.s.w.a.www.BasicAuthenticationFilter  : Did not process authentication request since failed to find username and password in Basic Authorization header

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking RequestCacheAwareFilter (12/16)

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.s.w.s.HttpSessionRequestCache        : matchingRequestParameterName is required for getMatchingRequest to lookup a value, but not provided

2024-05-03T12:28:58.976+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking SecurityContextHolderAwareRequestFilter (13/16)

2024-05-03T12:28:58.978+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking AnonymousAuthenticationFilter (14/16)

2024-05-03T12:28:58.978+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking ExceptionTranslationFilter (15/16)

2024-05-03T12:28:58.978+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.security.web.FilterChainProxy        : Invoking AuthorizationFilter (16/16)

2024-05-03T12:28:58.979+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] estMatcherDelegatingAuthorizationManager : Authorizing SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@7c884baa]

2024-05-03T12:28:58.981+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] estMatcherDelegatingAuthorizationManager : Checking authorization on SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@7c884baa] using org.springframework.security.authorization.AuthenticatedAuthorizationManager@455b9bc9

2024-05-03T12:28:58.981+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] w.c.HttpSessionSecurityContextRepository : Did not find SecurityContext in HttpSession 29D8D0A6BFDCB39EAEF8E2EE94D874F6 using the SPRING_SECURITY_CONTEXT session attribute

2024-05-03T12:28:58.981+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]

2024-05-03T12:28:58.981+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] .s.s.w.c.SupplierDeferredSecurityContext : Created SecurityContextImpl [Null authentication]

2024-05-03T12:28:58.983+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=29D8D0A6BFDCB39EAEF8E2EE94D874F6], Granted Authorities=[ROLE_ANONYMOUS]]

2024-05-03T12:28:58.984+09:00 TRACE 996 --- [b01] [nio-8090-exec-2] o.s.s.w.a.ExceptionTranslationFilter     : Sending AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=29D8D0A6BFDCB39EAEF8E2EE94D874F6], Granted Authorities=[ROLE_ANONYMOUS]] to authentication entry point since access is denied


- 실행 및 화면 확인 (시큐리티에서 제공하는 기본 login 화면)

http://localhost:8090/login

초기 ID : user   / PW : 로그에서 확인한 값 (매실행 시 변경) >> 접속확인

ex) 로그화면 아래 텍스트 

- Using generated security password: de1c3259-32f8-41de-9ba3-e244ea0ce779


2 Security 로그 세팅

-application.properties 파일에 소스 추가 

-application.properties

# security logging setting
logging.level.org.springframework.security=trace


3. Config 설정 및 로그확인 

- CustomSecurityConfig 파일 생성  

1. config 패키지 생성 >> 경로 : /main/java/{pakage name}/config

2. CustomSecurityConfig.java 클래스 생성 >> 1번 경로에 생성 

* filterChain 설정 시 기본 시큐리티에서 제공하는 기본 login 화면 볼 수 없으며,

초기 아이디 비밀번호 사용 할 수 없게됨 참고 ( ID : user )

Using generated security password: de1c3259-32f8-41de-9ba3-e244ea0ce779

This generated password is for development use only. Your security configuration must be updated before running your application in production.


-CustomSecurityConfig.java

package org.zerock.b01.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

@Configuration
@Log4j2
@RequiredArgsConstructor
public class CustomSecurityConfig {


//11개의 필터를 걸어서 권한을 체크하여 걸러줌
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
log.info("-----------------security configure--------------------")
        // http.formLogin(Customizer.withDefaults());  기본값
return http.build();
}


}

3. 인텔리제이 콘솔 로그 확인 

2024-05-03T18:09:02.417+09:00  INFO 5552 --- [b01] [  restartedMain] o.z.b01.config.CustomSecurityConfig      : -----------------security configure--------------------

4. webSecurityCustomizer 메서드 추가 :  static 경로 아래에 있으면 로그인 인증에서 제외

-CustomSecurityConfig.java

@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
log.info("---------------web configure-------------------");
// 정적 리소스 필터링 제외 (static 경로아래 있는 녀석들 실행 시 로그인 인증에서 제외됨)
return (web -> web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations()));
}

5. 로그 확인 

2024-05-03T18:35:45.434+09:00  INFO 8804 --- [b01] [  restartedMain] o.z.b01.config.CustomSecurityConfig      : ---------------web configure-------------------

2024-05-03T18:35:45.594+09:00  WARN 8804 --- [b01] [  restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

2024-05-03T18:35:45.627+09:00  INFO 8804 --- [b01] [  restartedMain] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]

6. 4번 내용 테스트를 위해서 로컬에 접속 시 인증이 안뜨는지 확인 ( 주의 /index 아님)  

= 로그인 인증 없이 접속되면 성공 

http://localhost:8090/


4. Security 추가 및 로그인 가능한 user1 설정 

- PasswordEncoderConfig 파일 생성 

1. config 경로 >> /main/java/{pakage name}/config

2. PasswordEncoderConfig.java 클래스 생성 >> 1번 경로에 생성 

-PasswordEncoderConfig.java

package org.zerock.b01.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class PasswordEncoderConfig {

// 순환 참조 문제를 해결하기 위해서 PasswordEncoder를 별도의 Configuration으로
// 등록하여 사용!
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

}


- CustomUserDetailsService 파일 생성 

1. security 패키지 생성 >> 경로 : /main/java/{pakage name}/security

2. CustomUserDetailsService.java 클래스 생성 >> 1번 경로에 생성

-CustomUserDetailsService.java

package org.zerock.b01.security;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
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.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.zerock.b01.config.PasswordEncoderConfig;

@Log4j2
@Service
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {

    private final PasswordEncoderConfig passwordEncoderConfig;
    //private PasswordEncoder passwordEncoder;  // 주입하면 순환구조 발생 final 제거

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.info("loadUserByUsername : " + username);

//userDeatils 객체로 반환하는 userDetails를 생성
UserDetails userDetails = User.builder().username("user1")
.password(passwordEncoderConfig.passwordEncoder().encode("1111")).authorities("ROLE_USER").build();

return userDetails;
}
}

3. CustomSecurityConfig.java 의 filterChain 메서드에 csrf(사용자인증값) 비활성화 및 로그인페이지 기본페이지에서 원하는경로로 지정

-CustomSecurityConfig.java

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    log.info("-----------------security configure--------------------");
    //로그인페이지 기본페이지에서 변경
    http.formLogin(form -> {
    form.loginPage("/member/login")
//로그인 성공 기본 페이지
.defaultSuccessUrl("/board/list");
    });
    //크롬 개발자도구 네트워크 >> 엘리먼트선택 >> 페이지로드 부분에서 확인가능한 csrf(사용자인증값) 비활성화
    http.csrf(httpSecurityCsrfConfigurer -> httpSecurityCsrfConfigurer.disable());
    return http.build();
}

4. 컨트롤러 (MemberController.java) login 메서드 생성 

-MemberController.java

package org.zerock.b01.controller;


import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.servlet.mvc.support.RedirectAttributes;
import org.zerock.b01.dto.MemberJoinDTO;
import org.zerock.b01.service.MemberService;

@Controller
@Log4j2
@RequiredArgsConstructor
@RequestMapping("/member/")
public class MemberController {

@Autowired
MemberService memberService;

@GetMapping("/login")
public void login(Model model) {
log.info("login ..........................");
}

}

5. 뷰 (login.html) 생성 : src\main\resources\templates\member

-login.html

<!DOCTYPE html>
<html xmlns:th="http://thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale">

<title>login</title>
<!--tymeleaf 형식으로 경로 수정 : th:href = "@{경로}"-->
<!-- Favicon-->
<link rel="icon" type="image/x-icon" th:href="@{/assets/favicon.icon}" />
<!-- Core theme CSS (includes Bootstrap)-->
<link th:href="@{/css/styles.css}" rel="stylesheet" />

</head>
<body class="align-middle">
<div class="container-fluid d-flex justify-content-center" style="height: 100vh">
<div class="card align-self-center">
<div class="card-header">
Login Page
</div>
<div class="card-body">
<th:block th:if="${param.logout != null}">
<h3>Logout</h3>
</th:block>
<!--form태그의 action 속성은 "/member/login" 으로 동일한 경로에 post방식으로 지정-->
<form id="registerForm" action="/member/login" method="post">
<!--username password input name 지정해야함-->
<div class="input-group mb-3">
<span class="input-group-text">아이디</span>
<input type="text" name="username" class="form-control" placeholder="USER ID">
</div>
<div class="input-group mb-3">
<span class="input-group-text">패스워드</span>
<input type="text" name="password" class="form-control" placeholder="PASSWORD">
</div>
<div class="input-group mb-3">
<input class="form-check-input" type="checkbox" name="remember-me">
<label class="form-check-label">
자동로그인
</label>
</div>
<div class="my-4">
<div class="float-end">
<button type="submit" class="btn btn-primary submitBtn">Login</button>
</div>
</div>
</form>
</div>
</div>
</div>
<h1>Login Page</h1>

</body>
</html>

6. 로컬 접속 >> user1 으로 로그인 >> 인텔리제이 콘솔 로그 확인 

http://localhost:8090/member/login

2024-05-03T13:16:42.220+09:00  INFO 6652 --- [b01] [nio-8090-exec-3] o.z.b.security.CustomUserDetailsService  : loadUserByUsername  : user1

2024-05-03T13:16:42.433+09:00 DEBUG 6652 --- [b01] [nio-8090-exec-3] o.s.s.a.dao.DaoAuthenticationProvider    : Authenticated user

2024-05-03T13:16:42.434+09:00 TRACE 6652 --- [b01] [nio-8090-exec-3] s.CompositeSessionAuthenticationStrategy : Preparing session with ChangeSessionIdAuthenticationStrategy (1/2)

2024-05-03T13:16:42.449+09:00 DEBUG 6652 --- [b01] [nio-8090-exec-3] .s.ChangeSessionIdAuthenticationStrategy : Changed session id from 67C078648AE455D4DA818FAA3DDCF9E8


5. 인증권한 설정

1. CustomSecurityConfig파일 클래스에 @EnableMethodSecurity 추가 

= @EnableMethodSecurity : 아래 두녀석을 사용할 수 있게끔 해줌 

@Configuration 과 같이 사용 (설정파일과 같이 사용해야함) 

@PreAuthorize: 메서드가 실행되기 전에 인증을 거친다.

@PostAuthorize: 메서드가 실행되고 나서 응답을 보내기 전에 인증을 거친다.

-CustomSecurityConfig.java

@Configuration
@Log4j2
@RequiredArgsConstructor
@EnableMethodSecurity
public class CustomSecurityConfig {

2. BoardController.java 파일 메핑메서드 부분에 @PreAuthorize 설정 : 일반 사용자 권한인 사람들만 접근 가능


@PreAuthorize("hasRole('USER')") // ROLE_USER과 같은 의미...로 특정 권한 사용자만 접근 가능하도록 설정. 
// (초기 id user를 말하는게 아니고 사용자 권한영역을 말함)
@GetMapping("/register")
public void registerGet() {

}

3. 테스트 

- 로그인 후 >> 아래 링크 접속 >> 접속 성공 

 http://localhost:8090/board/register

- 로그아웃 상태 ( 크롬 개발자도구 >> Application Tab >> 왼쪽 stoage 텝  Cookie 우클릭 clear ) 

>>  http://localhost:8090/board/register >> 재접속 >> 로그인 화면 노출 확인



* 다음글 

[SpringBoot] 스프링부트 프로젝트 생성 후 spring-security 사용 및 테스트하기2 login 설정~로그인 설정~(세팅 스프링 시큐리티 세션 스프링부트3.25  )_IntelliJ IDEA 2024.1JDK17 spring-boot test session http--++

https://rockbottomdevbus.blogspot.com/2024/05/springboot-spring-security-2-login-325.html

* 참고 

https://docs.spring.io/spring-security/reference/servlet/authentication/passwords/form.html

https://velog.io/@choidongkuen/Spring-Security-Spring-Security-Filter-Chain-%EC%97%90-%EB%8C%80%ED%95%B4

댓글

T O P