우선 스프링 시큐리티를 사용하기 위해
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
디펜던시를 추가해 주자
이렇게 하면 스프링 시큐리티를 쓸 준비는 끝난다
이제 회원가입을 위해 User Table과 User Model 을 생성해보자
이런식으로 추가 해줬다.
그후
package com.seogi.myhome.model;
import lombok.Data;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String username;
private String password;
private boolean enabled;
이렇게 모델 객체를 생성해준다.
그 후 config 패키지를 생성을 해주고
WebSecurityConfig를 만들어준다.
https://www.baeldung.com/spring-security-jdbc-authentication
사이트는 이곳을 참고 하였다.
package com.seogi.myhome.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/" , "/account/register","/css/**" ).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/account/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder()) // 비밀번호를 암호화 하는 작업
// 인증처리
.usersByUsernameQuery("select username,password,enabled "
+ "from user "
+ "where username = ?")
// 권한처리
.authoritiesByUsernameQuery("select u.username,r.name "
+ "from user_role ur inner join user u on ur.user_id = u.id "
+ "inner join role r on ur.role_id = r.id "
+ "where u.username = ?");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
이렇게 추가해준다.
이렇게 할 경우에 antMatchers 에 인증처리가 없어도 접속할 수있는
페이지를 설정해주고
loginPage는 login api를 설정해준다.ㅣ
그후 PasswordEndcoder를 설정하여 회원가입을 할때
비밀번호를 단반향으로 암호화에 필요한 걸 빈등록을해준다.
그 후 configureGlobal을 하나 만들어준다.
인증 처리에 관한 데이터 소스를 처리해준다.
이곳에 대해서는 나중에 many to many로 다대다 조인을 할 것이다.
그 후 role 테이블을 만들어 이곳에는 인증에 대한 테이블이다
조인에 필요한 테이블을 생성해 준다.
테이블을 생성해 주었다면 모델 객체도 만들어주자
package com.seogi.myhome.model;
import lombok.Data;
import javax.persistence.*;
import java.util.List;
@Entity
@Data
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
부트스트랩에서 로그인 페이지 샘플을 가져온다.
https://getbootstrap.com/docs/4.6/examples/
컨트롤러를 만들어 주어 로그인 페이지에 접근할 수 있도록 만들어준다.
@GetMapping("/login")
public String loing(){
return "account/login";
}
그 후 타임리프 th:if로
<div th:if="${param.error}" class="alert alert-danger" role="alert">
Invalid username and password.
</div>
</div>
<div th:if="${param.logout}" class="alert alert-light" role="alert">
로그아웃 되었습니다.
</div>
에러를 처리해준다.
이렇게 처리 되었다.
그 후 로그인을 위해 회원가입 페이지를 만들어야겠다.
회원가입 페이지는 간단하게 로그인 페이지를 카피하여 살짝 수정하여 재활용 하자
페이지까지 만들었다면
@ManyToMany 설정해준다.
@ManyToMany
@JoinTable( name = "user_role", joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")) // 조인될 상대 테이블을 적어준다.
private List<Role> roles = new ArrayList<>();
@ManyToMany(mappedBy = "roles")
private List<User> users;
이렇게 모델 객체에 추가하여준다.
으로 조인해준다.
그 후 UserRepository를 만들어준다.
package com.seogi.myhome.repository;
import com.seogi.myhome.model.Board;
import com.seogi.myhome.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User,Long> {
}
JPA를 쓸 준비는 끝낫다.
이제 컨트롤러를 작성해주자
@GetMapping ("/register")
public String register(){
return "account/register";
}
으로 접속 할 수있게 해주고
그 후 서비스를 작성해주자
package com.seogi.myhome.service;
import com.seogi.myhome.model.Role;
import com.seogi.myhome.model.User;
import com.seogi.myhome.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
public User save(User user){
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
user.setEnabled(true);
Role role = new Role();
role.setId(1);
user.getRoles().add(role);
return userRepository.save(user);
}
}
서비스에서는 Repositoy를 사용하기 위해
AutoWired로 추가해 준뒤
아까 빈 등록을 해준 비밀번호 단방향 암호화를 해줄
@Autowired
private PasswordEncoder passwordEncoder;
이 두개를 AutoWired로 추가 해준다.
Save()라는 메소드를 작성해준다.
먼저 파라미터로 비밀번호를 받아와 passwordencoder로 암호화를 해준뒤
유저 권한인 setEnabled를 true를 바꿔준다.
그후 Role 객체를 추가 해준다.
1번으로 설정 해준다.
1번은 Role_user 로 권한을 설정해준다.
그후
private List<Role> roles = new ArrayList<>();
아까 모델객체에서 추가해준 roles 를 ArrayList로 바꿔준다.
@PostMapping("/register")
public String register(User user){
userService.save(user);
return "redirect:/";
}
이제 컨트롤러를 완성시켜준다.
<form class="form-signin" th:action="@{/account/register}" method="post">
<a th:href="@{/}"><img class="mb-4" src="https://getbootstrap.com/docs/4.6/assets/brand/bootstrap-solid.svg" alt="" width="72" height="72"></a>
<h1 class="h3 mb-3 font-weight-normal">회원가입</h1>
<label for="username" class="sr-only">UserName</label>
<input type="text" id="username" class="form-control" name="username" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" name="password" required>
<div class="checkbox mb-3">
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2021</p>
</form>
이제 회원가입을 하면
이렇게 단방향으로 암호화가 되었다!
잘 안된다면 아래의 소스코드를 확인해보자!
https://github.com/MoonSeokHyun?tab=repositories
'Spring Boot > Restful-Api + Spring Boot' 카테고리의 다른 글
(Spring Boot JPA)ManyToOne 일대다 매핑을 이용한 게시글 쓰기 (0) | 2022.06.19 |
---|---|
스프링 시큐리티를 이용한 로그인 처리 (0) | 2022.06.18 |
스프링부트 타임리프 벨리데이션 체크를 해보자 (0) | 2022.06.15 |
Restful-API연습 (10) REST API Monitoring을 위한 Actuator 설정 (0) | 2022.06.12 |
RestFul API 연습(9) Swagger 사용 (0) | 2022.06.04 |