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);
}
}
Last updated