-
Notifications
You must be signed in to change notification settings - Fork 0
[feat/#9] 이메일 비밀번호 인증 필터 및 인증 provider 구현 #10
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
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
14e7f47
[feat/#9] 이메일 비밀번호 인증 필터 및 인증 provider 구현
sejoon00 c8b6a35
[fix] 동시성 테스트 DB h2 로 변경
sejoon00 24d496d
[fix] 동시성 중복 테스트 제거
sejoon00 44e718d
[fix/#9] 단순 이메일 조회 예외처리 로직 repository로 이동
sejoon00 88c2033
[fix/#9] parsing 예외, NotFound 예외 BadCredentialsException로 통일 및 이메일 검증…
sejoon00 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # This workflow uses actions that are not certified by GitHub. | ||
| # They are provided by a third-party and are governed by | ||
| # separate terms of service, privacy policy, and support | ||
| # documentation. | ||
| # This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created | ||
| # For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle | ||
|
|
||
| name: Gradle Package | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: | ||
| - "master" | ||
| - "develop" | ||
|
|
||
| jobs: | ||
| build: | ||
|
|
||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
|
|
||
| steps: | ||
| - name: checkout | ||
| uses: actions/checkout@v3 | ||
|
|
||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v3 | ||
| with: | ||
| java-version: '17' | ||
| distribution: 'temurin' | ||
|
|
||
|
|
||
| - name: build and test | ||
| run: | | ||
| chmod +x gradlew | ||
| ./gradlew build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 0 additions & 3 deletions
3
src/main/java/com/moplus/moplus_server/MoplusServerApplication.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
src/main/java/com/moplus/moplus_server/domain/auth/controller/AuthController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package com.moplus.moplus_server.domain.auth.controller; | ||
|
|
||
| import com.moplus.moplus_server.domain.auth.dto.request.AdminLoginRequest; | ||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.headers.Header; | ||
| import io.swagger.v3.oas.annotations.media.Schema; | ||
| import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
| import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/api/v1/auth") | ||
| @RequiredArgsConstructor | ||
| public class AuthController { | ||
|
|
||
| @Operation(summary = "어드민 로그인", description = "아아디 패스워드 로그인 후 토큰 발급합니다.") | ||
| @ApiResponses(value = { | ||
| @ApiResponse( | ||
| responseCode = "200", | ||
| description = "로그인 성공", | ||
| headers = { | ||
| @Header(name = "Authorization", description = "Access Token", schema = @Schema(type = "string")), | ||
| @Header(name = "RefreshToken", description = "Refresh Token", schema = @Schema(type = "string")) | ||
| } | ||
| ), | ||
| @ApiResponse(responseCode = "400", description = "잘못된 요청"), | ||
| @ApiResponse(responseCode = "401", description = "인증 실패") | ||
| }) | ||
| @PostMapping("/admin/login") | ||
| public void adminLogin( | ||
| @RequestBody AdminLoginRequest request | ||
| ) { | ||
| // 실제 처리는 Security 필터에서 이루어지며, 이 메서드는 Swagger 명세용입니다. | ||
| } | ||
| } |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/moplus/moplus_server/domain/auth/dto/request/AdminLoginRequest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package com.moplus.moplus_server.domain.auth.dto.request; | ||
|
|
||
| public record AdminLoginRequest( | ||
| String email, | ||
| String password | ||
| ) { | ||
| } |
42 changes: 42 additions & 0 deletions
42
src/main/java/com/moplus/moplus_server/domain/member/domain/Member.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package com.moplus.moplus_server.domain.member.domain; | ||
|
|
||
| import com.moplus.moplus_server.global.common.BaseEntity; | ||
| import jakarta.persistence.Column; | ||
| import jakarta.persistence.Entity; | ||
| import jakarta.persistence.EnumType; | ||
| import jakarta.persistence.Enumerated; | ||
| import jakarta.persistence.GeneratedValue; | ||
| import jakarta.persistence.GenerationType; | ||
| import jakarta.persistence.Id; | ||
| import lombok.AccessLevel; | ||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| @Getter | ||
| @Entity | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class Member extends BaseEntity { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Column(name = "member_id") | ||
| private Long id; | ||
|
|
||
| private String email; | ||
| private String password; | ||
|
|
||
| @Enumerated(EnumType.STRING) | ||
| private MemberRole role; | ||
|
|
||
| @Builder | ||
| public Member(String nickname, String email, String password, MemberRole role) { | ||
| this.email = email; | ||
| this.password = password; | ||
| this.role = role; | ||
| } | ||
|
|
||
| public boolean isMatchingPassword(String password) { | ||
| return this.password.equals(password); | ||
| } | ||
| } |
21 changes: 21 additions & 0 deletions
21
src/main/java/com/moplus/moplus_server/domain/member/domain/MemberRole.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.moplus.moplus_server.domain.member.domain; | ||
|
|
||
| import java.util.Arrays; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| @AllArgsConstructor | ||
| public enum MemberRole { | ||
| USER("ROLE_USER"), | ||
| ADMIN("ROLE_ADMIN"); | ||
|
|
||
| private final String value; | ||
|
|
||
| public static MemberRole findByKey(String value) { | ||
| return Arrays.stream(MemberRole.values()) | ||
| .filter(role -> role.value.equals(value)) | ||
| .findFirst() | ||
| .orElseThrow(() -> new IllegalArgumentException("No role with key: " + value)); | ||
| } | ||
| } |
15 changes: 15 additions & 0 deletions
15
src/main/java/com/moplus/moplus_server/domain/member/repository/MemberRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package com.moplus.moplus_server.domain.member.repository; | ||
|
|
||
| import com.moplus.moplus_server.domain.member.domain.Member; | ||
| import com.moplus.moplus_server.global.error.exception.ErrorCode; | ||
| import com.moplus.moplus_server.global.error.exception.NotFoundException; | ||
| import java.util.Optional; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface MemberRepository extends JpaRepository<Member, Long> { | ||
| Optional<Member> findByEmail(String email); | ||
|
|
||
| default Member findByEmailOrThrow(String email) { | ||
| return findByEmail(email).orElseThrow(() -> new NotFoundException(ErrorCode.MEMBER_NOT_FOUND)); | ||
| } | ||
| } |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/moplus/moplus_server/domain/member/service/MemberService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.moplus.moplus_server.domain.member.service; | ||
|
|
||
| import com.moplus.moplus_server.domain.member.domain.Member; | ||
| import com.moplus.moplus_server.domain.member.repository.MemberRepository; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class MemberService { | ||
|
|
||
| private final MemberRepository memberRepository; | ||
|
|
||
| @Transactional(readOnly = true) | ||
| public Member getMemberByEmail(String email) { | ||
| return memberRepository.findByEmailOrThrow(email); | ||
| } | ||
| } |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/moplus/moplus_server/global/config/properties/PropertiesConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package com.moplus.moplus_server.global.config.properties; | ||
|
|
||
| import com.moplus.moplus_server.global.properties.jwt.JwtProperties; | ||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
| import org.springframework.context.annotation.Configuration; | ||
|
|
||
| @EnableConfigurationProperties({ | ||
| JwtProperties.class | ||
| }) | ||
| @Configuration | ||
| public class PropertiesConfig { | ||
|
|
||
| } |
112 changes: 112 additions & 0 deletions
112
src/main/java/com/moplus/moplus_server/global/config/security/SecurityConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| package com.moplus.moplus_server.global.config.security; | ||
|
|
||
| import com.moplus.moplus_server.domain.member.service.MemberService; | ||
| import com.moplus.moplus_server.global.security.filter.EmailPasswordAuthenticationFilter; | ||
| import com.moplus.moplus_server.global.security.handler.EmailPasswordSuccessHandler; | ||
| import com.moplus.moplus_server.global.security.provider.EmailPasswordAuthenticationProvider; | ||
| import java.util.List; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.beans.factory.annotation.Value; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.security.authentication.AuthenticationManager; | ||
| import org.springframework.security.authentication.ProviderManager; | ||
| import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; | ||
| import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||
| import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; | ||
| import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; | ||
| import org.springframework.security.config.http.SessionCreationPolicy; | ||
| import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
| import org.springframework.security.web.SecurityFilterChain; | ||
| import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
| import org.springframework.web.cors.CorsConfiguration; | ||
| import org.springframework.web.cors.CorsConfigurationSource; | ||
| import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | ||
|
|
||
| @Configuration | ||
| @EnableWebSecurity | ||
| @RequiredArgsConstructor | ||
| public class SecurityConfig { | ||
|
|
||
| private final MemberService memberService; | ||
| private final EmailPasswordSuccessHandler emailPasswordSuccessHandler; | ||
| private final AuthenticationConfiguration authenticationConfiguration; | ||
|
|
||
| private String[] allowUrls = {"/", "/favicon.ico", "/swagger-ui/**", "/v3/**"}; | ||
|
|
||
| @Value("${cors-allowed-origins}") | ||
| private List<String> corsAllowedOrigins; | ||
|
|
||
| @Bean | ||
| public WebSecurityCustomizer configure() { | ||
| // filter 안타게 무시 | ||
| return (web) -> web.ignoring().requestMatchers(allowUrls); | ||
| } | ||
|
|
||
|
|
||
| @Bean | ||
| public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||
| http | ||
| .csrf(AbstractHttpConfigurer::disable) | ||
| .formLogin(AbstractHttpConfigurer::disable) | ||
| .cors(customizer -> customizer.configurationSource(corsConfigurationSource())) | ||
| .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) | ||
| .authorizeHttpRequests(request -> request | ||
| .requestMatchers(allowUrls).permitAll() | ||
| .anyRequest().authenticated()); | ||
|
|
||
| http | ||
| .exceptionHandling(exception -> | ||
| exception.authenticationEntryPoint((request, response, authException) -> | ||
| response.setStatus(HttpStatus.UNAUTHORIZED.value()))); // 인증,인가가 되지 않은 요청 시 발생시 | ||
|
|
||
| http | ||
| .addFilterAt(emailPasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); | ||
| // .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class) | ||
| // .addFilterBefore(new JwtExceptionFilter(), JwtAuthenticationFilter.class); | ||
|
|
||
| return http.build(); | ||
| } | ||
|
|
||
| @Bean | ||
| public EmailPasswordAuthenticationFilter emailPasswordAuthenticationFilter() throws Exception { | ||
| EmailPasswordAuthenticationFilter emailPasswordAuthenticationFilter = new EmailPasswordAuthenticationFilter( | ||
| authenticationManager(authenticationConfiguration)); | ||
| emailPasswordAuthenticationFilter.setFilterProcessesUrl("/api/v1/auth/admin/login"); | ||
| emailPasswordAuthenticationFilter.setAuthenticationSuccessHandler(emailPasswordSuccessHandler); | ||
| emailPasswordAuthenticationFilter.afterPropertiesSet(); | ||
| return emailPasswordAuthenticationFilter; | ||
| } | ||
|
|
||
| @Bean | ||
| public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { | ||
| ProviderManager providerManager = (ProviderManager) authenticationConfiguration.getAuthenticationManager(); | ||
| providerManager.getProviders().add(emailPasswordAuthenticationProvider()); | ||
| return configuration.getAuthenticationManager(); | ||
| } | ||
|
|
||
| @Bean | ||
| public EmailPasswordAuthenticationProvider emailPasswordAuthenticationProvider() { | ||
| return new EmailPasswordAuthenticationProvider(memberService); | ||
| } | ||
|
|
||
| @Bean | ||
| public CorsConfigurationSource corsConfigurationSource() { | ||
| CorsConfiguration configuration = new CorsConfiguration(); | ||
| configuration.setAllowedOrigins(corsAllowedOrigins); | ||
| configuration.addAllowedMethod("*"); | ||
| configuration.setAllowedHeaders(List.of("*")); // 허용할 헤더 | ||
| configuration.setAllowCredentials(true); | ||
|
|
||
| UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); | ||
| source.registerCorsConfiguration("/**", configuration); // 모든 경로에 적용 | ||
| return source; | ||
| } | ||
|
|
||
| @Bean | ||
| public BCryptPasswordEncoder bCryptPasswordEncoder() { | ||
| return new BCryptPasswordEncoder(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/main/java/com/moplus/moplus_server/global/properties/jwt/JwtProperties.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.moplus.moplus_server.global.properties.jwt; | ||
|
|
||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||
|
|
||
| @ConfigurationProperties(prefix = "jwt") | ||
| public record JwtProperties( | ||
| String accessTokenSecret, | ||
| String refreshTokenSecret, | ||
| Long accessTokenExpirationTime, | ||
| Long refreshTokenExpirationTime, | ||
| String issuer | ||
| ) { | ||
|
|
||
| public Long accessTokenExpirationMilliTime() { | ||
| return accessTokenExpirationTime * 1000; | ||
| } | ||
|
|
||
| public Long refreshTokenExpirationMilliTime() { | ||
| return refreshTokenExpirationTime * 1000; | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.