Security 권한 처리
SecurityConfig
package com.example.security1.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터(SecurityConfig)가 스프링 필터체인에 등록이 된다.
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true) //secured 어노테이션 활성화, preAuthorize, postAuthorize 어노테이션 활성화
public class SecurityConfig {
@Bean //해당 메서드의 리턴되는 오브젝트를 IoC로 등록해 준다.
public BCryptPasswordEncoder encodePwd() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeHttpRequests()
.requestMatchers("/user/**").authenticated() //인증만 되면 들어갈 수 있는 주소
.requestMatchers("/manager/**").hasAnyRole("ADMIN", "MANAGER")
.requestMatchers("/admin/**").hasAnyRole("ADMIN")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/loginForm")
//.usernameParameter("username2") -> html의 login받는 form에서 username을 username2로 바꾸면 PrincipalDetailsService의 username과 매칭이 되지 않는다.
//그럴때 usernameParameter() 를 이용하여 바꾸어 주면 된다.
.loginProcessingUrl("/login")
/*
loginProcessingUrl() :
"/login"이라는 주소가 호출이 되면 시큐리티가 낚아채서 대신 로그인을 진행해준다.
=> "/login"을 만들지 않아도 된다. security가 대신 해주기 때문에
*/
.defaultSuccessUrl("/"); //로그인이 완료되면 default인 메인페이지로 가게된다. 또한 특정페이지에서 로그인을 하면 그 특정페이지로 이동한다.
return http.build();
}
}
@EnableMethodSecurity가 추가되었다.
@EnableMethodSecurity
@Secured, @preAuthorize, @postAuthorize 어노테이션이 활성화가 된다.
indexController
package com.example.security1.controller;
import com.example.security1.model.User;
import com.example.security1.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller //View를 return
public class IndexController {
@Autowired
private UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
//localhost:8080/
//localhost:8080
@GetMapping({"","/"})
public String index() {
// 머스테치 기본폴더 src/main/resources/
// 뷰리졸버 설정 : templates (prefix), .mustache (suffix) 생략가능
return "index"; // src/main/resources/templates/index.mustache
}
@GetMapping("/user")
public @ResponseBody String user() {
return "user";
}
@GetMapping("/admin")
public @ResponseBody String admin() {
return "admin";
}
@GetMapping("/manager")
public @ResponseBody String manager() {
return "manager";
}
//SecurityConfig 를 생성후 자동으로 SpringSecurity에 의해 나오던 로그인 화면이 나오지 않게 된다.
@GetMapping("/loginForm")
public String login() {
return "loginForm";
}
@GetMapping("joinForm")
public String joinForm() {
return "joinForm";
}
@PostMapping("/join")
public String join(User user) {
user.setRole("ROLE_USER");
System.out.println(user);
/* 회원가입은 잘되지만 비밀번호는 1234
=> 시큐리티로 로그인 할 수 없다.
이유는 패스워드가 암호화가 안되었기 때문이다.
*/
String rawPassword = user.getPassword();
String encPassword = bCryptPasswordEncoder.encode(rawPassword);
user.setPassword(encPassword);
userRepository.save(user);
return "redirect:/loginForm";
//redirect: 를 붙이면 /loginForm이라는 함수를 호출한다.
}
@Secured("ROLE_ADMIN")
@GetMapping("/info")
public @ResponseBody String info() {
return "개인정보";
}
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')") //method가 실행되기 전에 수행
@GetMapping("/data")
public @ResponseBody String data() {
return "데이터정보";
}
}
info 메서드에
@Secured("ROLE_ADMIN")을 하게 되면
ADMIN 권한을 가진 계정만 해당 주소를 접근할 수 있다.
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')")는
ADMIN 권한과 MANAGER 권한을 가진 계정만 해당 주소로 접근할 수 있다.
method가 실행되기 직전에 실행된다.
@PostAuthorize는 이와 반대로
method가 수행된 직후 실행된다.
test
user1 : ROLE_USER 권한
manager : ROLE_MANGER 권한
admin : ROLE_ADMIN 권한
case1 : user1로 로그인하여 /info, /data 접근해 보기
result : user -> info 접근 불가
result : user -> data 접근 불가
case2 : manager로 로그인하여 /info, /data 접근해 보기
result : manager -> info 접근 불가
result : manager -> data 접근 가능
case3 : admin으로 로그인하여 /info, /data 접근해 보기
result : admin -> info 접근 가능
result : admin -> data 접근 가능
'자바 탐구' 카테고리의 다른 글
스프링) SpringSecurity - 7) Oauth2.0 구글 회원 프로필 정보 받아보기 (0) | 2023.05.26 |
---|---|
스프링) SpringSecurity - 6) Oauth2.0 구글 로그인 준비 (0) | 2023.05.26 |
스프링) SpringSecurity - 4) Security 로그인 (0) | 2023.05.26 |
스프링) SpringSecurity - 3) Security 회원 가입 (0) | 2023.05.26 |
스프링) SpringSecurity - 2) SecurityConfig 설정 (0) | 2023.05.26 |