개발자
데이터베이스에 user테이블과 role테이블 그리고 user_role테이블을 만들어 user_id와 role_id를 만들어 다대다 매핑을 하였습니다. 기존에는 configureGlobal방식으로 .authoritiesByUsernameQuery(“select u.email, 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.email = ?") 이런 방식으로 했는데 userDetailsService 인터페이스를 이용하여 로그인 처리를 하는 방식에서 유저의 권한을 어떻게 처리해야할지 모르겠습니다ㅠㅠㅠ 아직 시큐리티에 대해 잘 몰라 자세히 알려주시면 정말 감사하겠습니다 ㅠㅠ
답변 1
' UserDetailsService ' 인터페이스를 사용하여 로그인 처리를 할 때, 유저의 권한을 처리하기 위해서는 커스텀 ' UserDetailsService '를 구현하고, ' UserDetails ' 인터페이스를 구현한 클래스를 이용하여 권한 정보를 반환해야 합니다. 아래 예시 코드를 참조하세요. 1. 먼저 ' UserDetails ' 인터페이스를 구현한 커스텀 클래스를 만듭니다. 예를 들어 ' CustomUserDetails '라고 이름 짓겠습니다. 2. 다음으로 ' UserDetailsService ' 인터페이스를 구현한 커스텀 클래스를 만듭니다. 예를 들어 ' CustomUserDetailsService '라고 이름 짓겠습니다. 3. 마지막으로 ' WebSecurityConfigurerAdapter '를 상속받아 구성을 설정하고 ' CustomUserDetailsService '를 사용하도록 지정합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
#1 import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import java.util.Collection; import java.util.Set; import java.util.stream.Collectors; public class CustomUserDetails implements UserDetails { private String username; private String password; private Set<String> roles; public CustomUserDetails(String username, String password, Set<String> roles) { this.username = username; this.password = password; this.roles = roles; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()); } // ... 생략 (나머지 UserDetails 인터페이스 메서드 구현) } #2 import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.HashSet; import java.util.Set; @Service public class CustomUserDetailsService implements UserDetailsService { private final DataSource dataSource; public CustomUserDetailsService(DataSource dataSource) { this.dataSource = dataSource; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { String userQuery = "SELECT email, password FROM user WHERE email = ?"; String roleQuery = "SELECT 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.email = ?"; try (Connection conn = dataSource.getConnection()) { PreparedStatement userStmt = conn.prepareStatement(userQuery); userStmt.setString(1, username); ResultSet userRs = userStmt.executeQuery(); if (!userRs.next()) { throw new UsernameNotFoundException("User not found"); } String password = userRs.getString("password"); PreparedStatement roleStmt = conn.prepareStatement(roleQuery); roleStmt.setString(1, username); ResultSet roleRs = roleStmt.executeQuery(); Set<String> roles = new HashSet<>(); while (roleRs.next()) { roles.add(roleRs.getString("name")); } return new CustomUserDetails(username, password, roles); } catch (Exception e) { throw new RuntimeException(e); } } } #3 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation
커리어리 AI 봇의 답변을 평가해 주세요!
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!