Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step2 리뷰 요청드립니다~ #346

Open
wants to merge 10 commits into
base: sang-eun
Choose a base branch
from
8 changes: 0 additions & 8 deletions src/main/java/nextstep/DataLoader.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
package nextstep;

import lombok.AllArgsConstructor;
import nextstep.member.application.LoginMemberService;
import nextstep.member.application.MemberService;
import nextstep.member.application.dto.MemberRequest;
import nextstep.member.domain.Member;
import nextstep.member.domain.MemberRepository;
import nextstep.member.domain.RoleType;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Component
@AllArgsConstructor
Expand Down
7 changes: 2 additions & 5 deletions src/main/java/nextstep/MemberData.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package nextstep;

import lombok.AllArgsConstructor;
import nextstep.member.domain.Member;
import nextstep.member.domain.MemberRepository;
import nextstep.member.domain.RoleType;
import org.springframework.stereotype.Component;

import java.util.List;

Expand All @@ -17,6 +14,6 @@ public class MemberData {
private static final String MEMBER_PASSWORD = "password";
private static final int MEMBER_AGE = 20;

public static Member admin = new Member(ADMIN_EMAIL, ADMIN_PASSWORD, ADMIN_AGE, List.of(RoleType.ROLE_ADMIN.toString()));
public static Member member = new Member(MEMBER_EMAIL, MEMBER_PASSWORD, MEMBER_AGE, List.of(RoleType.ROLE_MEMBER.toString()));
public static Member admin = new Member(ADMIN_EMAIL, ADMIN_PASSWORD, ADMIN_AGE, List.of(RoleType.ROLE_ADMIN.name()));
public static Member member = new Member(MEMBER_EMAIL, MEMBER_PASSWORD, MEMBER_AGE, List.of(RoleType.ROLE_MEMBER.name()));
}
14 changes: 7 additions & 7 deletions src/main/java/nextstep/auth/AuthConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import nextstep.auth.context.SecurityContextPersistenceFilter;
import nextstep.auth.token.JwtTokenProvider;
import nextstep.auth.token.TokenAuthenticationInterceptor;
import nextstep.member.application.LoginMemberService;
import nextstep.member.application.UserDetailsService;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
Expand All @@ -16,20 +16,20 @@

@Configuration
public class AuthConfig implements WebMvcConfigurer {
private LoginMemberService loginMemberService;
private UserDetailsService userDetailsService;
private JwtTokenProvider jwtTokenProvider;

public AuthConfig(LoginMemberService loginMemberService, JwtTokenProvider jwtTokenProvider) {
this.loginMemberService = loginMemberService;
public AuthConfig(UserDetailsService userDetailsService, JwtTokenProvider jwtTokenProvider) {
this.userDetailsService = userDetailsService;
this.jwtTokenProvider = jwtTokenProvider;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SecurityContextPersistenceFilter());
registry.addInterceptor(new UsernamePasswordAuthenticationFilter(loginMemberService)).addPathPatterns("/login/form");
registry.addInterceptor(new TokenAuthenticationInterceptor(loginMemberService, jwtTokenProvider)).addPathPatterns("/login/token");
registry.addInterceptor(new BasicAuthenticationFilter(loginMemberService));
registry.addInterceptor(new UsernamePasswordAuthenticationFilter(userDetailsService)).addPathPatterns("/login/form");
registry.addInterceptor(new TokenAuthenticationInterceptor(userDetailsService, jwtTokenProvider)).addPathPatterns("/login/token");
registry.addInterceptor(new BasicAuthenticationFilter(userDetailsService));
registry.addInterceptor(new BearerTokenAuthenticationFilter(jwtTokenProvider));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package nextstep.auth.authentication;

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class AuthenticationToken {
private String principal;
private String credentials;
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/nextstep/auth/authentication/Authenticator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package nextstep.auth.authentication;

import nextstep.member.application.UserDetailsService;
import nextstep.member.domain.User;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

미션은 auth 패키지 내에 라이브러리를 제외한 비즈니스 패키지들이 들어오지 않아야 완료됩니다 😢
현재 auth 패키지가 member 에 의존하고 있어요

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public abstract class Authenticator implements HandlerInterceptor {

private final UserDetailsService userDetailsService;

public Authenticator(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
AuthenticationToken token = convert(request);
User user = userDetailsService.loadUserByUsername(token.getPrincipal());

checkAuthentication(user, token.getCredentials());
authenticate(user, response);

return false;
}

abstract public AuthenticationToken convert(HttpServletRequest request) throws IOException;

abstract public void authenticate(User user, HttpServletResponse response) throws IOException;

private void checkAuthentication(User user, String password) {
if (!user.checkPassword(password)) {
throw new AuthenticationException();
}
}
}
26 changes: 26 additions & 0 deletions src/main/java/nextstep/auth/authentication/Authorizator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package nextstep.auth.authentication;

import nextstep.auth.context.Authentication;
import nextstep.auth.context.SecurityContextHolder;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class Authorizator implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

try {
Authentication authentication = convert(request);
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (RuntimeException e){
return true;
}

return true;
}

abstract public Authentication convert(HttpServletRequest request);
}
Original file line number Diff line number Diff line change
@@ -1,50 +1,45 @@
package nextstep.auth.authentication;

import nextstep.auth.context.Authentication;
import nextstep.auth.context.SecurityContextHolder;
import nextstep.member.application.LoginMemberService;
import nextstep.member.domain.LoginMember;
import nextstep.member.application.UserDetailsService;
import nextstep.member.domain.User;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class BasicAuthenticationFilter implements HandlerInterceptor {
private LoginMemberService loginMemberService;
public class BasicAuthenticationFilter extends Authorizator {

public BasicAuthenticationFilter(LoginMemberService loginMemberService) {
this.loginMemberService = loginMemberService;
private final UserDetailsService userDetailsService;

public BasicAuthenticationFilter(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
String authCredentials = AuthorizationExtractor.extract(request, AuthorizationType.BASIC);
String authHeader = new String(Base64.decodeBase64(authCredentials));
public Authentication convert(HttpServletRequest request) {
AuthenticationToken token = getToken(request);
User loginMember = userDetailsService.loadUserByUsername(token.getPrincipal());

String[] splits = authHeader.split(":");
String principal = splits[0];
String credentials = splits[1];
checkAuthentication(token, loginMember);

AuthenticationToken token = new AuthenticationToken(principal, credentials);
return new Authentication(loginMember.getEmail(), loginMember.getAuthorities());
}

LoginMember loginMember = loginMemberService.loadUserByUsername(token.getPrincipal());
if (loginMember == null) {
throw new AuthenticationException();
}

if (!loginMember.checkPassword(token.getCredentials())) {
throw new AuthenticationException();
}
private AuthenticationToken getToken(HttpServletRequest request) {
String authCredentials = AuthorizationExtractor.extract(request, AuthorizationType.BASIC);
String authHeader = new String(Base64.decodeBase64(authCredentials));

Authentication authentication = new Authentication(loginMember.getEmail(), loginMember.getAuthorities());
String[] splits = authHeader.split(":");
String principal = splits[0];
String credentials = splits[1];

SecurityContextHolder.getContext().setAuthentication(authentication);
return new AuthenticationToken(principal, credentials);
}

return true;
} catch (Exception e) {
return true;
private void checkAuthentication(AuthenticationToken token, User user) {
if (!user.checkPassword(token.getCredentials())) {
throw new AuthenticationException();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
package nextstep.auth.authentication;

import nextstep.auth.context.Authentication;
import nextstep.auth.context.SecurityContextHolder;
import nextstep.auth.token.JwtTokenProvider;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public class BearerTokenAuthenticationFilter implements HandlerInterceptor {
public class BearerTokenAuthenticationFilter extends Authorizator {
private final JwtTokenProvider jwtTokenProvider;

public BearerTokenAuthenticationFilter(JwtTokenProvider jwtTokenProvider) {
this.jwtTokenProvider = jwtTokenProvider;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
String authCredentials = AuthorizationExtractor.extract(request, AuthorizationType.BEARER);
public Authentication convert(HttpServletRequest request) {
String authCredentials = AuthorizationExtractor.extract(request, AuthorizationType.BEARER);

jwtTokenProvider.validateToken(authCredentials);
String principal = jwtTokenProvider.getPrincipal(authCredentials);
List<String> roles = jwtTokenProvider.getRoles(authCredentials);

Authentication authentication = new Authentication(principal, roles);

SecurityContextHolder.getContext().setAuthentication(authentication);

return true;
} catch (RuntimeException exception) {
return true;
}
return jwtTokenProvider.toAuthentication(authCredentials);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package nextstep.member.domain;
package nextstep.auth.authentication;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoginMember 를 옮기시지 않아요 됩니다 😢



import nextstep.member.domain.Member;
import nextstep.member.domain.User;

import java.util.List;

public class LoginMember {
public class LoginMember implements User {
private String email;
private String password;
private List<String> authorities;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,45 +1,28 @@
package nextstep.auth.authentication;

import com.fasterxml.jackson.databind.ObjectMapper;
import nextstep.auth.context.Authentication;
import nextstep.auth.context.SecurityContext;
import nextstep.auth.context.SecurityContextHolder;
import nextstep.member.application.LoginMemberService;
import nextstep.member.domain.LoginMember;
import nextstep.member.domain.Member;
import org.springframework.web.servlet.HandlerInterceptor;
import nextstep.member.application.UserDetailsService;
import nextstep.member.domain.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.io.IOException;

public class UsernamePasswordAuthenticationFilter implements HandlerInterceptor {
private final LoginMemberService loginMemberService;
public class UsernamePasswordAuthenticationFilter extends Authenticator {

public UsernamePasswordAuthenticationFilter(LoginMemberService loginMemberService) {
this.loginMemberService = loginMemberService;
public UsernamePasswordAuthenticationFilter(UserDetailsService userDetailsService) {
super(userDetailsService);
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String email = request.getParameter("email");
String password = request.getParameter("password");

LoginMember member;

try {
member = loginMemberService.loadUserByUsername(email);
} catch (RuntimeException e) {
throw new AuthenticationException();
}

if (!member.checkPassword(password)) {
throw new AuthenticationException();
}
public AuthenticationToken convert(HttpServletRequest request) {
return new AuthenticationToken(request.getParameter("email"), request.getParameter("password"));
}

@Override
public void authenticate(User member, HttpServletResponse response) throws IOException {
Authentication authentication = new Authentication(member.getEmail(), member.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);

return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package nextstep.auth.authorization;

import nextstep.auth.authentication.LoginMember;
import nextstep.auth.context.Authentication;
import nextstep.auth.context.SecurityContextHolder;
import nextstep.member.domain.LoginMember;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/nextstep/auth/context/Authentication.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package nextstep.auth.context;

import lombok.EqualsAndHashCode;

import java.io.Serializable;
import java.util.List;

@EqualsAndHashCode
public class Authentication implements Serializable {
private Object principal;
private List<String> authorities;
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/nextstep/auth/token/JwtTokenProvider.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package nextstep.auth.token;

import io.jsonwebtoken.*;
import nextstep.auth.context.Authentication;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

Expand All @@ -14,6 +15,14 @@ public class JwtTokenProvider {
@Value("${security.jwt.token.expire-length}")
private long validityInMilliseconds;

public Authentication toAuthentication(String token) {
validateToken(token);
String principal = getPrincipal(token);
List<String> roles = getRoles(token);

return new Authentication(principal, roles);
}

public String createToken(String principal, List<String> roles) {
Claims claims = Jwts.claims().setSubject(principal);
Date now = new Date();
Expand Down
Loading