admin: 로그인 service 경로 분리

This commit is contained in:
geonhos 2024-05-21 12:01:27 +09:00
parent 1bc356e0a4
commit 618f92df7a
20 changed files with 115 additions and 176 deletions

View File

@ -1,4 +1,4 @@
package com.bpgroup.poc.admin.security.authentication.service;
package com.bpgroup.poc.admin.app.authentication;
import lombok.Data;
@ -6,7 +6,7 @@ import lombok.Data;
* 로그인 요청 Request
*/
@Data
public class LoginRequest {
public class AuthenticationRequest {
private String username;
private String password;
}

View File

@ -0,0 +1,27 @@
package com.bpgroup.poc.admin.app.authentication;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public class AuthenticationResponse {
private String resultCode;
private String resultMessage;
public static AuthenticationResponse success() {
AuthenticationResponse response = new AuthenticationResponse();
response.resultCode = "0000";
response.resultMessage = "Success";
return response;
}
public static AuthenticationResponse fail(String resultCode, String resultMessage) {
AuthenticationResponse response = new AuthenticationResponse();
response.resultCode = resultCode;
response.resultMessage = resultMessage;
return response;
}
}

View File

@ -0,0 +1,18 @@
package com.bpgroup.poc.admin.app.authentication;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class AuthenticationResult {
private final Long id;
private final String loginId;
private final String name;
private final String email;
public static AuthenticationResult of(Long id, String loginId, String name, String email) {
return new AuthenticationResult(id, loginId, name, email);
}
}

View File

@ -0,0 +1,36 @@
package com.bpgroup.poc.admin.app.authentication;
import com.bpgroup.poc.admin.app.authentication.exception.AdminNotFoundException;
import com.bpgroup.poc.admin.app.authentication.exception.DoNotHaveAnyMenuException;
import com.bpgroup.poc.admin.app.authentication.exception.InvalidPasswordException;
import com.bpgroup.poc.admin.domain.base.admin.entity.Admin;
import com.bpgroup.poc.admin.domain.base.admin.entity.AdminRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class AuthenticationService {
private final PasswordEncoder passwordEncoder;
private final AdminRepository adminRepository;
@Transactional
public AuthenticationResult login(String username, String password) throws AdminNotFoundException, InvalidPasswordException, DoNotHaveAnyMenuException {
Admin findAdmin = adminRepository.findByLoginId(username).orElseThrow(() -> new AdminNotFoundException(username));
if (!passwordEncoder.matches(password, findAdmin.getPassword())) {
throw new InvalidPasswordException(username);
}
return AuthenticationResult.of(
findAdmin.getId(),
findAdmin.getLoginId(),
findAdmin.getName(),
findAdmin.getLoginId()
);
}
}

View File

@ -1,4 +1,4 @@
package com.bpgroup.poc.admin.security.authentication.service.exception;
package com.bpgroup.poc.admin.app.authentication.exception;
public class AdminNotFoundException extends Exception {
public AdminNotFoundException(String message) {

View File

@ -1,4 +1,4 @@
package com.bpgroup.poc.admin.security.authentication.service.exception;
package com.bpgroup.poc.admin.app.authentication.exception;
public class DoNotHaveAnyMenuException extends Exception {
public DoNotHaveAnyMenuException() {

View File

@ -1,4 +1,4 @@
package com.bpgroup.poc.admin.security.authentication.service.exception;
package com.bpgroup.poc.admin.app.authentication.exception;
public class InvalidPasswordException extends Exception {
public InvalidPasswordException(String message) {

View File

@ -1,4 +1,4 @@
package com.bpgroup.poc.admin.security.authorization.service;
package com.bpgroup.poc.admin.app.authorization;
import com.bpgroup.poc.admin.domain.base.admin.entity.Admin;
import com.bpgroup.poc.admin.domain.base.admin.entity.AdminRepository;

View File

@ -1,4 +1,4 @@
package com.bpgroup.poc.admin.fitler;
package com.bpgroup.poc.admin.filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;

View File

@ -3,10 +3,10 @@ package com.bpgroup.poc.admin.security;
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationEntryPoint;
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationFilter;
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationProvider;
import com.bpgroup.poc.admin.security.authentication.service.LoginService;
import com.bpgroup.poc.admin.app.authentication.AuthenticationService;
import com.bpgroup.poc.admin.security.authorization.CustomAccessDeniedHandler;
import com.bpgroup.poc.admin.security.authorization.CustomAuthorizationManager;
import com.bpgroup.poc.admin.security.authorization.service.AuthorizationService;
import com.bpgroup.poc.admin.app.authorization.AuthorizationService;
import com.bpgroup.poc.admin.security.jwt.JwtTokenConstants;
import com.bpgroup.poc.admin.security.jwt.JwtTokenValidateFilter;
import lombok.RequiredArgsConstructor;
@ -36,7 +36,7 @@ public class SecurityConfig {
private static final String LOGOUT_PATH = "/logout";
private static final String ERROR_PATH = "/error";
private final LoginService loginService;
private final AuthenticationService authenticationService;
private final AuthorizationService authorizationService;
@ -89,7 +89,7 @@ public class SecurityConfig {
@Bean
public CustomAuthenticationProvider customAuthenticationProvider() {
return new CustomAuthenticationProvider(loginService);
return new CustomAuthenticationProvider(authenticationService);
}
@Bean

View File

@ -1,42 +0,0 @@
package com.bpgroup.poc.admin.security.authentication;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
public class AuthenticationDetail {
private String loginId;
private String name;
private String email;
@Builder
public static AuthenticationDetail of(String loginId, String name, String email) {
AuthenticationDetail authenticationDetail = new AuthenticationDetail();
authenticationDetail.loginId = loginId;
authenticationDetail.name = name;
authenticationDetail.email = email;
return authenticationDetail;
}
public String toJsonString() {
try {
return new ObjectMapper().writeValueAsString(this);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static AuthenticationDetail fromJsonString(String jsonString) {
try {
return new ObjectMapper().readValue(jsonString, AuthenticationDetail.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,8 +1,8 @@
package com.bpgroup.poc.admin.security.authentication;
import com.bpgroup.poc.admin.security.authentication.service.exception.AdminNotFoundException;
import com.bpgroup.poc.admin.security.authentication.service.exception.DoNotHaveAnyMenuException;
import com.bpgroup.poc.admin.security.authentication.service.exception.InvalidPasswordException;
import com.bpgroup.poc.admin.app.authentication.exception.AdminNotFoundException;
import com.bpgroup.poc.admin.app.authentication.exception.DoNotHaveAnyMenuException;
import com.bpgroup.poc.admin.app.authentication.exception.InvalidPasswordException;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

View File

@ -1,6 +1,6 @@
package com.bpgroup.poc.admin.security.authentication;
import com.bpgroup.poc.admin.security.authentication.service.LoginResponse;
import com.bpgroup.poc.admin.app.authentication.AuthenticationResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
@ -26,7 +26,7 @@ public class CustomAuthenticationFailureHandler implements AuthenticationFailure
}
String jsonResponse = new ObjectMapper().writeValueAsString(
LoginResponse.fail(
AuthenticationResponse.fail(
"9999",
failMessage
)

View File

@ -1,10 +1,11 @@
package com.bpgroup.poc.admin.security.authentication;
import com.bpgroup.poc.admin.security.authentication.service.LoginRequest;
import com.bpgroup.poc.admin.app.authentication.AuthenticationRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
@ -19,8 +20,7 @@ import java.nio.charset.StandardCharsets;
public class CustomAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
private static final String DEFAULT_LOGIN_REQUEST_URL = "/login";
private static final String HTTP_METHOD = "POST";
private static final String CONTENT_TYPE = "application/json";
private boolean postOnly = true;
private static final String CONTENT_TYPE = MediaType.APPLICATION_JSON_VALUE;
public CustomAuthenticationFilter() {
super(new AntPathRequestMatcher(DEFAULT_LOGIN_REQUEST_URL, HTTP_METHOD)); // 위에서 설정한 /oauth2/login/* 요청에, GET으로 요청을 처리하기 위해 설정한다.
@ -33,13 +33,13 @@ public class CustomAuthenticationFilter extends AbstractAuthenticationProcessing
// 요청에 대한 유효성 검사
isValidated(request);
LoginRequest loginRequest = new ObjectMapper().readValue(
AuthenticationRequest authenticationRequest = new ObjectMapper().readValue(
StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8),
LoginRequest.class
AuthenticationRequest.class
);
String username = loginRequest.getUsername();
String password = loginRequest.getPassword();
String username = authenticationRequest.getUsername();
String password = authenticationRequest.getPassword();
if (username == null || password == null) {
throw new AuthenticationServiceException("DATA IS MISS");
@ -52,7 +52,7 @@ public class CustomAuthenticationFilter extends AbstractAuthenticationProcessing
}
private void isValidated(HttpServletRequest request) {
if (this.postOnly && !request.getMethod().equals(HTTP_METHOD)) {
if (!request.getMethod().equals(HTTP_METHOD)) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}

View File

@ -1,7 +1,7 @@
package com.bpgroup.poc.admin.security.authentication;
import com.bpgroup.poc.admin.security.authentication.service.LoginResult;
import com.bpgroup.poc.admin.security.authentication.service.LoginService;
import com.bpgroup.poc.admin.app.authentication.AuthenticationResult;
import com.bpgroup.poc.admin.app.authentication.AuthenticationService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@ -12,7 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final LoginService loginService;
private final AuthenticationService authenticationService;
@Transactional
@Override
@ -21,31 +21,20 @@ public class CustomAuthenticationProvider implements AuthenticationProvider {
String username = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
LoginResult loginResult = loginService.login(username, password);
AuthenticationResult authenticationResult = authenticationService.login(username, password);
return buildAuthenticationToken(loginResult);
return buildAuthenticationToken(authenticationResult);
} catch (Exception e) {
throw new AuthenticationFailException("로그인에 실패하였습니다.", AuthenticationFailReason.from(e));
}
}
private UsernamePasswordAuthenticationToken buildAuthenticationToken(LoginResult result) {
UsernamePasswordAuthenticationToken token = UsernamePasswordAuthenticationToken.authenticated(
private UsernamePasswordAuthenticationToken buildAuthenticationToken(AuthenticationResult result) {
return UsernamePasswordAuthenticationToken.authenticated(
result.getLoginId(),
null,
null
);
token.setDetails(
AuthenticationDetail.builder()
.loginId(result.getLoginId())
.name(result.getName())
.email(result.getEmail())
.build()
.toJsonString()
);
return token;
}
@Override

View File

@ -1,6 +1,6 @@
package com.bpgroup.poc.admin.security.authentication;
import com.bpgroup.poc.admin.security.authentication.service.LoginResponse;
import com.bpgroup.poc.admin.app.authentication.AuthenticationResponse;
import com.bpgroup.poc.admin.security.jwt.JwtTokenGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.Cookie;
@ -25,7 +25,7 @@ public class CustomAuthenticationSuccessHandler implements AuthenticationSuccess
response.addCookie(jwtCookie);
String jsonResponse = new ObjectMapper().writeValueAsString(
LoginResponse.success()
AuthenticationResponse.success()
);
response.getWriter().write(jsonResponse);

View File

@ -1,28 +0,0 @@
package com.bpgroup.poc.admin.security.authentication.service;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public class LoginResponse {
private String resultCode;
private String resultMessage;
private String token;
public static LoginResponse success() {
LoginResponse response = new LoginResponse();
response.resultCode = "0000";
response.resultMessage = "Success";
return response;
}
public static LoginResponse fail(String resultCode, String resultMessage) {
LoginResponse response = new LoginResponse();
response.resultCode = resultCode;
response.resultMessage = resultMessage;
return response;
}
}

View File

@ -1,20 +0,0 @@
package com.bpgroup.poc.admin.security.authentication.service;
import lombok.Getter;
@Getter
public class LoginResult {
private Long id;
private String loginId;
private String name;
private String email;
public static LoginResult of(Long id, String loginId, String name, String email) {
LoginResult loginResult = new LoginResult();
loginResult.id = id;
loginResult.loginId = loginId;
loginResult.name = name;
loginResult.email = email;
return loginResult;
}
}

View File

@ -1,41 +0,0 @@
package com.bpgroup.poc.admin.security.authentication.service;
import com.bpgroup.poc.admin.domain.base.admin.entity.Admin;
import com.bpgroup.poc.admin.domain.base.admin.entity.AdminRepository;
import com.bpgroup.poc.admin.security.authentication.service.exception.AdminNotFoundException;
import com.bpgroup.poc.admin.security.authentication.service.exception.DoNotHaveAnyMenuException;
import com.bpgroup.poc.admin.security.authentication.service.exception.InvalidPasswordException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class LoginService {
private final AdminRepository adminRepository;
private final PasswordEncoder passwordEncoder;
@Transactional
public LoginResult login(String username, String password) throws AdminNotFoundException, InvalidPasswordException, DoNotHaveAnyMenuException {
Optional<Admin> admin = adminRepository.findByLoginId(username);
if (admin.isEmpty()) {
throw new AdminNotFoundException(username);
}
if (!passwordEncoder.matches(password, admin.get().getPassword())) {
throw new InvalidPasswordException(username);
}
return LoginResult.of(
admin.get().getId(),
admin.get().getLoginId(),
admin.get().getName(),
admin.get().getLoginId()
);
}
}

View File

@ -1,6 +1,6 @@
package com.bpgroup.poc.admin.security.authorization;
import com.bpgroup.poc.admin.security.authorization.service.AuthorizationService;
import com.bpgroup.poc.admin.app.authorization.AuthorizationService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;