Skip to content

Commit

Permalink
Merge pull request #126 from 0702Yoon/main
Browse files Browse the repository at this point in the history
refactor : CustomerDetails class 생성으로 member가 UserDetails 상속 받지 않도록 변경
  • Loading branch information
0702Yoon authored Oct 2, 2024
2 parents 5f0c509 + 4342c11 commit 2876ca7
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.example.bigbrotherbe.domain.member.entity;

import java.util.Collection;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

@RequiredArgsConstructor
@Getter
public class CustomerDetails implements UserDetails {

private final Member member;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return member.getAffiliations().stream()
.map(affiliationMember -> new SimpleGrantedAuthority(affiliationMember.getRole()))
.collect(Collectors.toList());
}

@Override
public String getPassword() {
return member.getPassword();
}

@Override
public String getUsername() {
return member.getEmail();
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class Member implements UserDetails {
public class Member {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down Expand Up @@ -68,27 +68,6 @@ public class Member implements UserDetails {
// 정적 필드로 정의된 정규식 패턴 객체
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)$");

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.affiliations.stream()
.map(affiliationMember -> new SimpleGrantedAuthority(affiliationMember.getRole()))
.collect(Collectors.toList());
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Builder
public Member(String username, String password, String email, String is_active, LocalDateTime createAt, LocalDateTime updateAt) {
Expand All @@ -104,11 +83,6 @@ public Member(String username, String password, String email, String is_active,
}


@Override
public boolean isEnabled() {
return true;
}

public void changePassword(String memberPass) {
this.password = memberPass;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,29 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.filter.OncePerRequestFilter;

@RequiredArgsConstructor
@Slf4j
public class JwtAuthenticationFilter extends GenericFilterBean {
public class JwtAuthenticationFilter extends OncePerRequestFilter {

private final JwtTokenProvider jwtTokenProvider;

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
protected void doFilterInternal(@NonNull HttpServletRequest servletRequest,
@NonNull HttpServletResponse servletResponse,
FilterChain filterChain) throws ServletException, IOException {
try {
String token = resolveToken(request);
String token = resolveToken(servletRequest);
if (token != null && jwtTokenProvider.validateToken(token)
&& jwtTokenProvider.checkTokenType(token)) {
// 유효한 엑세스 토큰이 있는 경우
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ public Long getAffiliationIdByMemberId(Long memberId, String affiliation) {

public JwtToken createAuthenticationToken(String email, String password) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(email, password);
Authentication authentication;
try {
authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
Authentication authentication = authenticationManagerBuilder.getObject()
.authenticate(authenticationToken);
return jwtTokenProvider.generateToken(authentication);
} catch (Exception e) {
throw new BusinessException(MISMATCH_PASSWORD);
}
return jwtTokenProvider.generateToken(authentication);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.example.bigbrotherbe.global.exception.enums.ErrorCode;
import com.example.bigbrotherbe.global.jwt.entity.JwtToken;
import com.example.bigbrotherbe.global.jwt.entity.TokenDto;
import com.example.bigbrotherbe.global.security.CustomUserDetailsService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
Expand All @@ -19,8 +20,6 @@
import io.jsonwebtoken.security.Keys;

import java.security.Key;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.stream.Collectors;

Expand All @@ -42,9 +41,12 @@ public class JwtTokenProvider {
private static final long ACCESS_TIME = 10 * 60 * 1000L; // 10분
private static final long REFRESH_TIME = 30 * 60 * 1000L; //30분

public JwtTokenProvider(@Value("${jwt.secret}") String secretKey) {
private final CustomUserDetailsService customerDetailsService;

public JwtTokenProvider(@Value("${jwt.secret}") String secretKey,CustomUserDetailsService customerDetailsService) {
byte[] keyBytes = Decoders.BASE64.decode(secretKey);
this.key = Keys.hmacShaKeyFor(keyBytes);
this.customerDetailsService = customerDetailsService;
}

// Member 정보를 가지고 Access Token, RefreshToken을 생성하는 메서드
Expand Down Expand Up @@ -80,21 +82,15 @@ public Authentication getAuthentication(String token) {
if (claims.get("auth") == null) {
throw new RuntimeException("권한 정보가 없는 토큰입니다.");
}

Collection<? extends GrantedAuthority> authorities =
Arrays.stream(claims.get("auth").toString().split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());

UserDetails principal = new org.springframework.security.core.userdetails.User(claims.getSubject(), "", authorities);
log.info("Authorities from token: {}", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
UserDetails principal = customerDetailsService.loadUserByUsername(
claims.getSubject());
return new UsernamePasswordAuthenticationToken(principal, "", principal.getAuthorities());
}

public boolean validateToken(String token) {

try {
Claims claims = Jwts.parserBuilder()
Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
Expand Down Expand Up @@ -188,4 +184,5 @@ private String resolveToken(String token) {
}
throw new BusinessException(ErrorCode.ILLEGAL_HEADER_PATTERN);
}

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.example.bigbrotherbe.global.security;

import com.example.bigbrotherbe.domain.member.entity.CustomerDetails;
import com.example.bigbrotherbe.domain.member.entity.Member;
import com.example.bigbrotherbe.domain.member.repository.MemberRepository;
import com.example.bigbrotherbe.global.exception.BusinessException;
import com.example.bigbrotherbe.global.exception.enums.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
Expand All @@ -16,15 +18,9 @@ public class CustomUserDetailsService implements UserDetailsService {

@Override
public UserDetails loadUserByUsername(String userEmail) throws UsernameNotFoundException {
return memberRepository.findByEmail(userEmail).map(this::createUserDetails).orElseThrow(()-> new UsernameNotFoundException("해당하는 멤버를 찾을 수 없습니다."));
Member member = memberRepository.findByEmail(userEmail).orElseThrow(() -> new BusinessException(
ErrorCode.NO_EXIST_EMAIL));
return new CustomerDetails(member);
}

// 해당하는 User 의 데이터가 존재한다면 UserDetails 객체로 만들어서 return
private UserDetails createUserDetails(Member member) {
return User.builder()
.username(member.getEmail())
.password(member.getPassword())
.authorities(member.getAuthorities())
.build();
}
}

0 comments on commit 2876ca7

Please sign in to comment.