스프링 부트 환경에서 Spring Security를 이용한 권한, redirect, 로그인 페이지 구현
1. 스프링 시큐리티 설정 추가하기
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Gradle
compile("org.springframework.boot:spring-boot-starter-security")
2. 스프링 시큐리티 기본 적용
위와 같이 디펜던시 추가 후 아무 페이지도 만들지 않고 서버를 실행하여
http://localhost:8080 으로 진입하면 페이지를 찾을 수 없다면서 404 상태코드가 출력되어야 한다.
하지만, 실제로 접속해보면 로그인 페이지가 출력된다.
localhost를 요청했지만 302번의 상태코드가 나오면서 redirect 되었다는 것을 알 수 있다.
그렇게 redirect되어 응답한 페이지가 /login 페이지인 것이다.
이것은 스프링부트 시큐리티가 기본으로 제공하는 기능이다.
스프링부트 시큐리티는 누군가 우리 서버에 들어오려고 할 때, 인증이 되지 않은 모든 사용자를 낚아채서
인증을 받게끔 강제적으로 시큐리티가 제공하는 로그인 페이지로 redirection 하는 것이다.
3. 스프링부트 시큐리티 설정
메인 경로에 config 패키지를 만들고, 그 안에 SecurityConfig.java 파일을 만든다.
그리고 해당 클래스에 WebSecurityConfigurerAdapter를 extends 한다.
WebSecurityConfigurerAdapter를 상속받으면 시큐리티 설정 파일로 인식이 된다.
그리고,
@EnableWebSecurity 어노테이션으로 해당 파일로 시큐리티를 활성화 시키고
@Configuration 어노테이션으로 IoC 컨테이너에 등록한다.
그 후 configure(HttpSecurity http)를 Overide 해준다.
package com.GStagram.config;
import org.springframework.context.annotation.Configuration;
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 // 해당 파일로 시큐리티를 활성화
@Configuration // IOC
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
}
}
Overiding된 configure 내부를 보면 super.configure(http); 라는 기능이 활성화 되어있다.
이 기능이 시큐리티가 인증되지 않은 요청을 낚아채서 login 페이지로 응답하게 해준다
이 부분을 지우고 설정을 다시 해준다.
package com.GStagram.config;
import org.springframework.context.annotation.Configuration;
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 // 해당 파일로 시큐리티를 활성화
@Configuration // IOC
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// super 삭제 - 기존 시큐리티가 가지고 있는 기능이 다 비활성화됨.
// 인증이 되지 않은 모든 사용자는 로그인 페이지로 이동
http
.authorizeRequests() // URL별 관리
.antMatchers("/auth/**", "/css/**","/images/**","/js/**","/h2-console/**").permitAll() //유저 관련 페이지만 접근 가능
.anyRequest().authenticated() // 설정된 값들 이외 나머지 URL은 인증된 사용자만 접근 가능
.and()
.formLogin()
.loginPage("/auth/login") // GET
.defaultSuccessUrl("/");
}
}
- authorizeRequests() 메서드를 사용하여 URL별로 관리
- antMatchers() 메서드는 요청이 들어오는 경로를 지정해주는 곳이다.
auth(로그인화면), css, images, js, h2-console로 들어오는 요청은 permitAll을 하여 허용한다. - anyRequest().authenticated() 메서드를 이용하여
위에 경로를 제외한 나머지 URL은 인증된 사용자만 접근이 가능하도록 한다. - formLogin().loginPage() 메서드로 로그인 페이지 경로를 설정한다.
설정 후 로그인 컨트롤러와 로그인 페이지 mustache파일을 생성하고 테스트를 진행한다.
AuthController
package com.GStagram.domain.auth;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AuthController {
@GetMapping("/auth/login")
public String loginPage() {
return "auth/login";
}
}
login.mustache
{{>layouts/header}}
<div class="page_container">
<div class="login_form_container">
<div class="login_form_imgbox">
<img src="/images/imag.jpg" alt="img" height="600">
</div>
<form action="/user/login" method="post">
<div class="login_form_box">
<div class="login_logo_box">
<img src="/images/logo.png" alt="Logo" width="175">
</div>
<div class="login_input_box">
<div class="form-floating mb-3">
<input type="email" class="form-control" id="user_email" placeholder="Email">
<label for="floatingInput">이메일</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="user_password" placeholder="Password">
<label for="floatingPassword">비밀번호</label>
</div>
</div>
<div class="login_btn_wrap">
<button type="submit" class="login_btn" id="login_btn">로그인</button>
<hr align="center" style="border: solid 1px gray; width: 300px;">
<button type="button" class="login_btn_img"><img src="/images/login_btn_google.png" width="220"></button>
<button type="button" class="login_btn_img"><img src="/images/login_btn_naver.png" width="220"></button>
<button type="button" class="login_btn_img"><img src="/images/login_btn_kakao.png" width="220"></button>
<span>계정이 없으신가요? <a href='/user/signup'>가입하기</a> </span>
</div>
</div>
</form>
</div>
</div>
{{>layouts/footer}}
결과물
정상적으로 설정한 시큐리티 설정이 적용되었다.