이전글
https://greed-yb.tistory.com/224
SecurityConfig 에서 권한이 있는지 확인할 때 hasAnyRole()에 있는 권한만 허용이 된다.
예) http.authorizeRequests().requestMatchers("/").hasAnyRole("권한1" , "권한2" , "권한3")
권한을 관리하는 페이지가 있다면 하드코딩으로 관리 할 수 없기 때문에 방식을 추가하였다
import com.example.practice.security.handler.WebAccessDeniedHandler;
import com.example.practice.security.handler.WebAuthenticationEntryPoint;
import com.example.practice.service.role.RoleService;
import com.example.practice.vo.RoleVo;
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.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import java.util.ArrayList;
import java.util.List;
@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
@Autowired
private RoleService roleService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// 권한 생성에 따른 role 추가
List<RoleVo> vo = roleService.roleInfo();
List<String> arrList = new ArrayList<>();
for (int i = 0; i < vo.size(); i++) {
arrList.add(String.valueOf(vo.get(i).getRoleId()));
}
String[] roleArray = arrList.toArray(new String[arrList.size()]);
////////
http.csrf().disable(); // @EnableWebSecurity 이 csrf 공격을 방지하기 때문에 해당 기능을 disable로 변경
http
.authorizeRequests()
.requestMatchers("/").hasAnyRole(roleArray) // 권한체크 - 내부적으로 ROLE_ 을 붙이기 때문에 ROLE_ 뒷부분만 적어준다
.......
.......
.......
.......
.......
.......
사용하던 쿼리를 그대로 사용하느라 List<RoleVo> 에서 List<String> 으로 작업을 두번하게 되었다
List<String> 으로 받아오길 바란다
AuthProvider
이전글
https://greed-yb.tistory.com/226
권한을 확인하기 위해 코드가 수정되었다
import com.example.practice.service.user.UserService;
import com.example.practice.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class AuthProvider implements AuthenticationProvider {
@Autowired
private UserService userService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = (String) authentication.getPrincipal(); // 로그인 Form에 name에 입력한 Id
String password = (String) authentication.getCredentials(); // 로그인 Form에 name에 입력한 password
PasswordEncoder passwordEncoder = userService.passwordEncoder();
UsernamePasswordAuthenticationToken token;
UserVo userVo = userService.getUserById(username);
if (userVo != null && passwordEncoder.matches(password, userVo.getPassword())) { // 일치하는 user 정보가 있는지 확인
List<GrantedAuthority> roles = new ArrayList<>();
// 권한 부여
roles.add(new SimpleGrantedAuthority(userVo.getRole()));
// 인증된 user 정보를 token에 담는다
token = new UsernamePasswordAuthenticationToken(userVo.getId(), null, roles);
return token;
}
// 문제가 생겼을때 Exception을 반환하지 않으면 정상적으로 실행된 것으로 인식한다
throw new BadCredentialsException("잘못된 정보입니다.");
}
@Override
public boolean supports(Class<?> authentication) {
return true;
}
}
service
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 유저 정보
public UserVo getUserById(String id) {
return userMapper.getUserById(id);
}
}
mapper.class
@Mapper
public interface UserMapper {
/**
* 유저 정보
* @param username
* @return
*/
UserVo getUserById(String username);
}
mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.practice.mapper.user.UserMapper">
<!-- 회원 정보 가져오기 -->
<select id="getUserById" resultType="com.example.practice.vo.UserVo">
SELECT
ID,
PASSWORD,
NAME,
AGE,
'ROLE_' || ROLE AS ROLE,
ZIP_CODE,
STREET_ADR,
DETAIL_ADR,
CREATE_TIME,
ENABLED,
SECURITY_NUMBER,
PHONE_NUMBER,
POSITION,
DEPARTMENT,
PROFILE
FROM USERMEMBER
WHERE id = #{username}
</select>
</mapper>
mapper 에서 가져올 때 Role 에 "ROLE_" 을 붙여서 가져온다
권한이 추가 및 삭제가 돼도 동적으로 권한을 체크할 수 있게 되었다
'개발 > Security' 카테고리의 다른 글
[SpringBoot] Security + JWT(Access , Refresh) - JwtTokenUtil (0) | 2024.09.25 |
---|---|
[SpringBoot] Security + JWT(Access , Refresh) - SecurityConfig (0) | 2024.09.25 |
[SpringBoot] Security 로그인 인증, 인가(9) - 실행하기 (0) | 2023.04.30 |
[SpringBoot] Security 로그인 인증, 인가(8) - Controller (0) | 2023.04.30 |
[SpringBoot] Security 로그인 인증, 인가(7) - html (0) | 2023.04.30 |
댓글