* 이번장에서는 스프링 시큐리티에서 제공하는 로그인 화면이 아닌

   개발자가 직접 만들 로그인 화면으로 커스터마이징을 할 것이다.

   이때, 로그인 화면의 변경과 같이 클라이언트가 파라미터로 전송하는 아이디와 패스워드도 저장 할 것이다 **

 

 

IDE : STS4 - Spring Tool Suite-4

 

** 개발환경

spring boot 3.3.5

spring security 6.0

oracle 11g

mybatis

gradle

 

-


spring security작업에 앞서

login view와 컨트롤러 작업을 먼저 한다.

 

login.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>Login</h2>
	<form action="login" method="post">
		ID<input type="text" name="username">
		pw<input type="password" name="password">
		<input type="submit" value="login">
	</form>
</body>
</html>

 

login url 처리 추가 (컨트롤러)

 

<확인> 서버를 재시작하고 http://www.localhost:8080/login 이라고 입력해 본다. 

결과 : 막혀있을 것이다.. 이유는 spring scurity의 인가정책에서 거부 되어 있을 것이다. 이 부분을 다음과 같이 수정한다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
	@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http	.csrf((csrfConfig) -> csrfConfig.disable())
                .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/","/login").permitAll()
                         .requestMatchers("/freeboard*").hasRole("USER")
                         .anyRequest().authenticated() 
                )
                ;  
        return http.build();
    }	

}

 

이제 정상적으로 로그인 화면이 보여진다.

 

 


login 관련 Spring security를 작성하자

 

SecurityFilterChain 에 로그인관련 설정을 한다. 

 

<Check>

1. usernameParameter("username")  username은 클라이언트가 넘겨 주는 아이디를 저장하고 있는 변수이다.

2. passwordParameter("password")  password는 클라이언트가 넘겨 주는 비밀번호 변수이다.

3. loginPage("/login")  인가받지 않은 사용자에게 login url로 이동하게 하는 것. 즉, 인가 받지 않은 url인 경우 자동으로 

                                     login url로 이동하고 컨트롤러는 해당 뷰로 응답한다.

4. defaultSuccessUrl("/") 로그인 성공시 이동하려는 url 정의

5. failureForwardUrl("/login") 로그인 실패시 이동하려는 url정의

  login.html 과 securityFilterChain과 비교  - 서로 일치해야 한다.
                                                                        - Spring security 내부에서는 username과 password 변수로 인식 됨
                                                                        -  이런 이유로 html파일부터 변수명을 같게 코딩 함
 

 

@Configuration
@EnableWebSecurity
public class SecurityConfig {
	@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http	.csrf((csrfConfig) -> csrfConfig.disable())
                .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/","/login").permitAll()
                         .requestMatchers("/freeboard*").hasRole("USER")
                         .anyRequest().authenticated() 
                )
                .formLogin(formLogin->formLogin     
                        .loginPage("/login")        // 로그인 url
                        .defaultSuccessUrl("/")     // 성동하면 이동할 url
                        .usernameParameter("username")  //  클라이언트가 넘겨 주는 아이디 변수값
                        .passwordParameter("password")  //  클라이언트가 넘겨 주는 비밀번호 변수값
                        .failureForwardUrl("/login") // 인증 실패시 이동할 url
                )
                ;  
        return http.build();
    }	

}

 

 

 정상 작동하는지 테스트 해 보자. 

테스트 url 결과 설명
http://www.localhost8080/ home.html 나옴 인가 정책에서   permitAll
http://www.localhost8080/freeboard login.html 나옴 인가가 되어 있지 않아서 
loginPage("/login") 설정에 의해
로그인 화면이 나옴
http://www.localhost8080/login login.html 나옴 인가 정책에서   permitAll

 

 

> 위 테스트 내역 중 2번째 테스트를 실행해 보겠습니다.

 

이렇게 입력하면 아래와 같이 이동한다.

 

 

 

 

 

 

 

 

 

ID는 user 

PW는 암호를 입력해보자

이제는 로그인 창이 아닌 다음과 같은 창이 나올 것이다.  정상이다.. 이유는 로그인은 성공했으나 freeboard는 USER권한 자만 가능하다.. 즉 아직 권한을 부여 받지 않은 상태이므로 아직까지는 접근할 수 없다. 

 

 

더 정확하게 테스트를 하기 위해서

컨트롤러에 url 매핑을 추가하고 뷰를 하나더 만들어 보자

 

study.html도 만들어 보자

 

 

다시 테스트 해 보자

테스트 url 결과 설명
http://www.localhost8080/ home.html 나옴 인가 정책에서   permitAll
http://www.localhost8080/freeboard
로그인은 되었으나 USER권한이 없음
http://www.localhost8080/login login.html 나옴 인가 정책에서   permitAll
http://www.localhost8080/study study.html 나옴 인가정책에서
anyRequest().authenticated()

 

 

다음에는 인증과 권한 부여를 실제 데이터베이스에서 조회하는 방법으로 커스터마이징을 할 것이다.

 

~~

+ Recent posts