- 목표 : 폼 로그인을 통해 인증을 완료하고 권한설정을 통해 특정 페이지에 엑세시 할 수 있도록 합니다.
- admin은 admin 페이지만 superadmin은 admin, superadmin페이지에 접근할 수 있습니다.
- 생성파일
- config
- SecurityConfig.java
- Controller
- AdminController.java
- LoginController.java
- Model
- Role.java
- AdminUser.java
- Service
- CustomUserDetailsService
- Repository
- AdminUserRepository
- config
Role.java 생성
@AllArgsConstructor
@Getter
public enum Role {
SUPERADMIN("ROLE_SUPERADMIN,ROLE_ADMIN"),
ADMIN("ROLE_ADMIN");
private String value;
}
AdminUser.java 생성
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
public class AdminUser implements UserDetails {
@Id
private Long id;
@Setter
private String adminId;
@Setter
private String password;
@Setter
private String role;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<>();
for(String s: role.split(",")){
authorities.add(new SimpleGrantedAuthority(s));
}
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return adminId;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
AdminUserRepository.java 생성
public interface AdminUserRepository extends JpaRepository<AdminUser, Long> {
Optional<AdminUser> findByAdminId(String adminId);
}
CustomUserDetailsService.java 생성
@Slf4j
@RequiredArgsConstructor
@Service
public class CustomUserDetailsService implements UserDetailsService {
private final AdminRepository adminRepository;
private final BCryptPasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<AdminUser> adminUser = adminRepository.findByAdminId(username);
if(adminUser.isPresent()){
AdminUser admin = adminUser.get();
AdminUser authUser = AdminUser.builder()
.id(admin.getId())
.adminId(admin.getAdminId())
.password(passwordEncoder.encode(admin.getPassword()))
.role(admin.getRole())
.build();
return authUser;
}else{
return AdminUser.builder()
.id(1l)
.adminId("qwe")
.password(passwordEncoder.encode("qwe"))
.role(Role.ADMIN.getValue())
.build();
}
}
}
LoginController.java 생성
@Controller
public class LoginController {
@GetMapping("/")
public String loginForm(){
return "loginForm";
}
}
AdminController.java 생성
@RequiredArgsConstructor
@Controller
public class AdminController {
@GetMapping("/admin")
public String admin(){
return "admin";
}
@GetMapping("/superadmin")
public String superadmin(){
return "superadmin";
}
@GetMapping("/accessDenied")
public String accessDenied(){
return "accessDenied";
}
}
SecurityConfig.java 생성
@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.csrf().disable()
.headers().frameOptions().sameOrigin()
.and()
.authorizeRequests()
.antMatchers("/","/h2-console","/register").permitAll()
.antMatchers("/superadmin", "/admin").hasRole("SUPERADMIN")
.antMatchers("/admin").hasRole("ADMIN")
.and()
.formLogin()
.loginPage("/")
.defaultSuccessUrl("/admin")
.usernameParameter("adminId")
.passwordParameter("password")
.and()
.logout()
.logoutSuccessUrl("/")
.invalidateHttpSession(true).deleteCookies("JSESSIONID") //세션 날리기
.and()
.exceptionHandling()
.accessDeniedPage("/accessDenied");
return http.build();
}
}
loginForm.html 생성
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/" method="post">
<input type="text" name="adminId" placeholder="myadmin">
<input type="password" name="password" placeholder="password">
<button type="submit">Login</button>
</form>
</body>
</html>
admin.html 생성
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1> Admin Page </h1>
<form action="/logout">
<button type="submit">logout</button>
</form>
</body>
</html>
superadmin.html 생성
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1> Super Page </h1>
<form action="/logout">
<button type="submit">logout</button>
</form>
</body>
</html>
accessdenied.html 생성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1> AccessDenied Page </h1>
<form action="/logout">
<button type="submit">logout</button>
</form>
</body>
</html>
'Spring Boot' 카테고리의 다른 글
[Security] Security Exception (0) | 2023.10.17 |
---|---|
[Security] 스프링 시큐리티 아키텍처 (0) | 2023.10.12 |