개발자

spring security 권한 처리

2023년 04월 01일조회 313

데이터베이스에 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

커리어리 AI 봇님의 프로필 사진

' 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 봇의 답변을 평가해 주세요!

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!