Spring Seucurity를 설정하다 보면 UserDetailsService를 통해 가입된 회원인지 확인하여 반환하는 메서드를 구현하게 된다.
Spring Security Config
@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
public class SecurityConfig {
...
@Bean
public UserDetailsService userDetailsService() {
return email -> memberRepository.findByMemberEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("존재하지 않는 회원입니다."));
}
}
이렇게 작성하고 나면, 바로 빨간불이 들어오면서Bad return type in lambda expression: Member cannot be converted to UserDetails
라는 에러 메시지를 개발자에게 보여주게 된다.
Member Entity
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long memberId;
@Column(unique = true)
private String memberEmail;
private String memberPassword;
@Column(unique = true)
private String memberNickname;
private MemberStatus memberStatus;
private String memberSNSProvider;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "blog_no")
private Blog blog;
}
위와 같은 상황일 때 일반적인 User(Member) Entity를 UserDetails으로 사용할 수 있는 방법이 있다.
바로 UserDetails의 구현체로 implements를 받는 것이다.
그 후 UserDetails의 인터페이스를 모두 구현해 주면 된다.
public class Member implements UserDetails {
...
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singletonList(new SimpleGrantedAuthority(memberStatus.name()));
}
@Override
public String getPassword() {
return memberPassword;
}
@Override
public String getUsername() {
return memberEmail;
}
@Override
public boolean isAccountNonExpired() {
return memberStatus.isAccountNonExpired(); // MemberStatus를 기반으로 반환
}
@Override
public boolean isAccountNonLocked() {
return memberStatus.isAccountNonLocked(); // MemberStatus를 기반으로 반환
}
@Override
public boolean isCredentialsNonExpired() {
return memberStatus.isCredentialsNonExpired(); // MemberStatus를 기반으로 반환
}
@Override
public boolean isEnabled() {
return memberStatus.isEnabled();
}
}
이렇게 UserDetails를 구현하고 나면, Config에서 반환되던 Bad return type in lambda expression: Member cannot be converted to UserDetails
에러는 사라지게 된다.
UserDetails
UserDetails는 Spring Security가 사용자의 인증을 처리하는 데 필요한 사용자 정보를 제공하는, 사용자의 정보
(사용자 이름, 비밀번호, 권한, 계정 만료, 비밀번호 만료, 계정 잠금 등)를 담고 있는 인터페이스이다. 해당 인터페이스에서 구현을 요구하는 메서드는 다음과 같다.
- Collection<? extends GrantedAuthority> getAuthorities(): 사용자에게 부여된 권한(롤)을 GrantedAuthority 객체의 컬렉션으로 반환
- String getPassword(): 사용자의 암호화된 비밀번호를 반환
- String getUsername(): 사용자의 이름을 반환
- boolean isAccountNonExpired(): 사용자 계정이 만료되지 않았는지 여부를 반환
- boolean isAccountNonLocked(): 사용자 계정이 잠기지 않았는지 여부를 반환
- boolean isCredentialsNonExpired(): 사용자의 비밀번호가 만료되지 않았는지 여부를 반환
- boolean isEnabled(): 사용자 계정이 활성화되었는지 여부를 반환
참조
UserDetails (spring-security-docs-manual 5.5.8 API)
Provides core user information. Implementations are not used directly by Spring Security for security purposes. They simply store user information which is later encapsulated into Authentication objects. This allows non-security related user information (s
docs.spring.io
https://www.baeldung.com/spring-security-authentication-with-a-database
'Server > Spring&Spring Boot' 카테고리의 다른 글
[Spring] Spotless + Pre Commit (0) | 2023.08.20 |
---|---|
[Spring] @Controller, @Service, @Repository 어노테이션 차이점. 나만의 @Component 어노테이션 생성 (4) | 2023.04.18 |
[Refactor] boolean을 사용하여 메서드 정리 (0) | 2023.04.01 |
[Spring] @Builder 사용시, 초기화해야할 필드가 존재할 때 발생하는 에러. @Builder will ignore the initializing expression entirely (0) | 2023.03.25 |
[Docs] Spring Rest Docs HTML 출력하는 법. (0) | 2023.03.22 |
Spring Seucurity를 설정하다 보면 UserDetailsService를 통해 가입된 회원인지 확인하여 반환하는 메서드를 구현하게 된다.
Spring Security Config
@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
public class SecurityConfig {
...
@Bean
public UserDetailsService userDetailsService() {
return email -> memberRepository.findByMemberEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("존재하지 않는 회원입니다."));
}
}
이렇게 작성하고 나면, 바로 빨간불이 들어오면서Bad return type in lambda expression: Member cannot be converted to UserDetails
라는 에러 메시지를 개발자에게 보여주게 된다.
Member Entity
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long memberId;
@Column(unique = true)
private String memberEmail;
private String memberPassword;
@Column(unique = true)
private String memberNickname;
private MemberStatus memberStatus;
private String memberSNSProvider;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "blog_no")
private Blog blog;
}
위와 같은 상황일 때 일반적인 User(Member) Entity를 UserDetails으로 사용할 수 있는 방법이 있다.
바로 UserDetails의 구현체로 implements를 받는 것이다.
그 후 UserDetails의 인터페이스를 모두 구현해 주면 된다.
public class Member implements UserDetails {
...
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singletonList(new SimpleGrantedAuthority(memberStatus.name()));
}
@Override
public String getPassword() {
return memberPassword;
}
@Override
public String getUsername() {
return memberEmail;
}
@Override
public boolean isAccountNonExpired() {
return memberStatus.isAccountNonExpired(); // MemberStatus를 기반으로 반환
}
@Override
public boolean isAccountNonLocked() {
return memberStatus.isAccountNonLocked(); // MemberStatus를 기반으로 반환
}
@Override
public boolean isCredentialsNonExpired() {
return memberStatus.isCredentialsNonExpired(); // MemberStatus를 기반으로 반환
}
@Override
public boolean isEnabled() {
return memberStatus.isEnabled();
}
}
이렇게 UserDetails를 구현하고 나면, Config에서 반환되던 Bad return type in lambda expression: Member cannot be converted to UserDetails
에러는 사라지게 된다.
UserDetails
UserDetails는 Spring Security가 사용자의 인증을 처리하는 데 필요한 사용자 정보를 제공하는, 사용자의 정보
(사용자 이름, 비밀번호, 권한, 계정 만료, 비밀번호 만료, 계정 잠금 등)를 담고 있는 인터페이스이다. 해당 인터페이스에서 구현을 요구하는 메서드는 다음과 같다.
- Collection<? extends GrantedAuthority> getAuthorities(): 사용자에게 부여된 권한(롤)을 GrantedAuthority 객체의 컬렉션으로 반환
- String getPassword(): 사용자의 암호화된 비밀번호를 반환
- String getUsername(): 사용자의 이름을 반환
- boolean isAccountNonExpired(): 사용자 계정이 만료되지 않았는지 여부를 반환
- boolean isAccountNonLocked(): 사용자 계정이 잠기지 않았는지 여부를 반환
- boolean isCredentialsNonExpired(): 사용자의 비밀번호가 만료되지 않았는지 여부를 반환
- boolean isEnabled(): 사용자 계정이 활성화되었는지 여부를 반환
참조
UserDetails (spring-security-docs-manual 5.5.8 API)
Provides core user information. Implementations are not used directly by Spring Security for security purposes. They simply store user information which is later encapsulated into Authentication objects. This allows non-security related user information (s
docs.spring.io
https://www.baeldung.com/spring-security-authentication-with-a-database
'Server > Spring&Spring Boot' 카테고리의 다른 글
[Spring] Spotless + Pre Commit (0) | 2023.08.20 |
---|---|
[Spring] @Controller, @Service, @Repository 어노테이션 차이점. 나만의 @Component 어노테이션 생성 (4) | 2023.04.18 |
[Refactor] boolean을 사용하여 메서드 정리 (0) | 2023.04.01 |
[Spring] @Builder 사용시, 초기화해야할 필드가 존재할 때 발생하는 에러. @Builder will ignore the initializing expression entirely (0) | 2023.03.25 |
[Docs] Spring Rest Docs HTML 출력하는 법. (0) | 2023.03.22 |