[Spring]Spring Security_3

김피자·2023년 3월 9일
0

Spring

목록 보기
18/28
post-thumbnail


이전 코드에서 user, manager, admin url요청이 들어오면 권한이 있는 사람만 접근하도록 했고, 접근이 없는 사람이 들어오려하면 로그인 페이지가 나오는 것을 확인했다. 그 외 다른 페이지들은 모두 접근을 허용해 두었었다.

user, manager, admin으로 접근 요청이 들어오면 인증을 위한 로그인 폼으로 이동하게 수정해보자.

IndexController 수정

package com.cos.security1.controller;

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

loginForm.html 생성

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>login page</title>
</head>
<body>
<h1>로그인 페이지</h1>
<hr/>
<form>
    <input type="text" name="username" placeholder="Username"/> <br/>
    <input type="password" name="password" placeholder="Password"/> <br/>
    <button>로그인</button>
</form>
</body>
</html>


이제 서버를 실행해 user, manager, admin 페이지를 요청하면 로그인 페이지로 이동하는 것을 볼 수 있다.

이제 회원가입을 구현해보자


User 테이블 생성

package com.cos.security01.model;

import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.hibernate.annotations.CreationTimestamp;
import lombok.Data;

// ORM - Object Relation Mapping

@Data
@Entity
public class User {
    @Id // primary key
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String username;
    private String password;
    private String email;
    private String role; //ROLE_USER, ROLE_ADMIN
    @CreationTimestamp
    private Timestamp createDate;
}

User 테이블을 생성했다.

회원가입

package com.cos.security01.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class IndexController {

    @GetMapping({"","/"})
    public String index(){

        return "index";
    }

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

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

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

    //스프링 시큐리티가 로그인 url을 낚아챈다.
    @GetMapping("/loginForm")
    public String loginForm(){
        return "loginForm";
    }

    @GetMapping("/joinForm")
    public String joinForm(){
        return "joinForm"; //회원가입 페이지 
    }

    @PostMapping("/join")
    public String join(){
        return "join"; //실제회원가입
    }
}

indexController 수정

  • login -> loginForm
  • joinForm 추가
  • joinProc 삭제

SecurityConfig 수정

 @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests()
                .antMatchers("/user/**").authenticated()
                .antMatchers("/manager/**").access("hasAnyRole('ROLE_MANAGER','ROLE_ADMIN')")
                .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginPage("/loginForm");

        return http.build();
    }

아래서 4번째 줄 loginForm으로 수정

loginForm.html 수정

<form>
    ...
</form>
<!--회원가입 링크 추가-->
<a href="/joinForm">회원가입을 아직 하지 않으셨나요?</a>
</body>
</html>

joinForm.html 생성

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>회원가입 페이지</title>
</head>
<body>
<h1>회원가입 페이지</h1>
<hr/>
<form action="/join" method="POST">
    <input type="text" name="username" placeholder="Username"/> <br/>
    <input type="password" name="password" placeholder="Password"/> <br/>
    <input type="email" name="email" placeholder="Email"/> <br/>
    <button>회원가입</button>
</form>
</body>
</html>

UserRepository 생성

package com.cos.security01.repository;

import com.cos.security01.model.User;
import org.springframework.data.jpa.repository.JpaRepository;


public interface UserRepository extends JpaRepository <User, Integer> {

}

repository 패키지를 만들고 그 안에 UserRepository를 만들었다.

근데 왜 @Repository 어노테이션을 사용안하고 JpaRepository를 상속받았을까?

그 이유는 JpaRepository는 기본 CRUD 메소드를 가지고 있는 메소드여서 내가 이를 따로 안 만들고 재활용할 수 있다.

그리고 JpaRepository를 상속받으면 IoC 컨테이너에 자동 등록된다.

IndexController 수정

@Autowired
    private UserRepository userRepository;

@PostMapping ("/join")
    public String join(User user){
        System.out.println(user);
        user.setRole("ROLE_USER");
        userRepository.save(user); 

        return "join"; //실제회원가입
    }

일단 임의로 user의 role 컬럼에 "ROLE_USER"라고 값을 입력했다.

이렇게 하고 실행하면 유저 가입이 제대로 실행되는 것을 확인할 수 있는데!!!
Spring Security로 로그인을 할 수가 없다.

SecurityConfig 수정

 @Bean
    public BCryptPasswordEncoder encodePwd(){
        return new BCryptPasswordEncoder();
    } //해당메소드의 리턴되는 오브젝트를 ioc로 등록해준다

encodePwd() 메소드 추가

@Bean을 하면 해당 메소드에서 리턴되는 오브젝트를 IoC로 등록해준다.

IndexController 수정

 @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

@PostMapping ("/join")
    public String join(User user){
    	//처음에 사용자가 입력한 값 출력
        System.out.println(user);
        
        user.setRole("ROLE_USER");
        String rawPassword = user.getPassword();
        String encPassword = bCryptPasswordEncoder.encode(rawPassword);
        user.setPassword(encPassword);
        userRepository.save(user);
        
        //암호화 적용 후 값 출력
        System.out.println(user);
        
        return "redirect:/loginForm"; //redirect를 하면 loginForm함수를 호출해준다
    }

이렇게 들어온 password를 시큐리티를 적용하여 암호화하여 등록하는 코드를 작성했다.

출력

User(id=0, username=123, password=123, email=123@123.com, role=null, createDate=null)

User(id=2, username=123, password=$2a$10$hTR3auQslSFvPHSb0XfBFeS2iIHMpv5XYMDpJGUce6c3XHflYbqsa, email=123@123.com, role=ROLE_USER, createDate=2023-03-09 15:41:06.006)

이렇게 내가 123이라고 입력했던 비밀번호에 스프링 시큐리티가 적용되어 DB에 입력되는 것을 볼 수 있다.

끝!@@@@!!!

profile
제로부터시작하는코딩생활

0개의 댓글