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

[TNT-28] feat: Authentication Filter 구현 #9

Merged
merged 79 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from 78 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
2765da8
feat: cors 설정 구현
fakerdeft Dec 28, 2024
bbd6f6d
style: naver 코드 컨벤션 커스텀 추가
fakerdeft Dec 28, 2024
397688b
feat: redis 설정 구현
fakerdeft Dec 28, 2024
348aa14
feat: webClient 설정 구현
fakerdeft Dec 28, 2024
4881e56
feat: cors 설정 구현
fakerdeft Dec 28, 2024
57e3db9
Merge branch 'develop' of https://github.com/YAPP-Github/25th-App-Tea…
fakerdeft Jan 4, 2025
19cbf55
Merge branch 'develop' of https://github.com/YAPP-Github/25th-App-Tea…
fakerdeft Jan 4, 2025
7df0f63
[TNT-76] feat: 세션 필터 구현 중
fakerdeft Jan 4, 2025
4a22cd0
[TNT-28] feat: cors 설정 삭제
fakerdeft Jan 5, 2025
287a966
[TNT-28] feat: 파일 위치 수정
fakerdeft Jan 5, 2025
a98cdbc
[TNT-28] feat: 커스텀 세션 객체 구현
fakerdeft Jan 5, 2025
a5090c1
[TNT-28] feat: BaseTimeEntity 구현
fakerdeft Jan 5, 2025
3ec4f7a
[TNT-28] chore: TSID 라이브러리 추가
fakerdeft Jan 5, 2025
ddcebf1
[TNT-28] refactor: value에 json 구조로 저장하도록 수정
fakerdeft Jan 5, 2025
88df790
[TNT-28] feat: findByIdAndDeletedAt 메서드 추가
fakerdeft Jan 5, 2025
436f484
[TNT-28] feat: Member entity 구현
fakerdeft Jan 5, 2025
f60cdda
[TNT-28] refactor: 접근 제어자, 변수명 수정
fakerdeft Jan 5, 2025
2dd0d6a
[TNT-28] feat: 세션 필터 추가
fakerdeft Jan 5, 2025
8523fdb
[TNT-28] feat: 세션 인증 로직 구현
fakerdeft Jan 5, 2025
2ac8730
[TNT-28] chore: TSID 라이브러리 변경
fakerdeft Jan 5, 2025
7e22fab
[TNT-28] chore: gradle 버전 8.5로 수정
fakerdeft Jan 5, 2025
fff07b4
[TNT-28] refactor: tsid 어노테이션 추가
fakerdeft Jan 5, 2025
38ee34f
[TNT-28] refactor: repository 어노테이션 추가
fakerdeft Jan 5, 2025
f71c593
[TNT-28] refactor: 생성자 파라미터에 id 추가
fakerdeft Jan 5, 2025
f1668bb
Merge branch 'develop' of https://github.com/YAPP-Github/25th-App-Tea…
fakerdeft Jan 5, 2025
de025d6
[TNT-28] feat: unauthorized 예외 생성
fakerdeft Jan 5, 2025
b3f7b7a
[TNT-28] chore: error 디렉토리 커버리지 검증 배제
fakerdeft Jan 5, 2025
1ac7bde
[TNT-28] refactor: 401 예외 추가, 접근 제어자 수정
fakerdeft Jan 5, 2025
0c56e0e
[TNT-28] refactor: 상태 필드 제거
fakerdeft Jan 5, 2025
8144fe5
[TNT-28] refactor: 세션 검증 로직 수정
fakerdeft Jan 5, 2025
446702c
[TNT-28] refactor: 인증 로직 수정, 401 예외 추가
fakerdeft Jan 5, 2025
4356b0b
[TNT-28] feat: SessionServiceTest 구현
fakerdeft Jan 5, 2025
aace3c2
[TNT-28] feat: MemberTest 구현
fakerdeft Jan 5, 2025
f0ac237
[TNT-28] feat: MemberIntegrationTest 구현
fakerdeft Jan 5, 2025
0786625
[TNT-28] refactor: memberRepository 참조 제거
fakerdeft Jan 5, 2025
11e8c66
[TNT-28] refactor: 공백 제거, 응답 구조 수정
fakerdeft Jan 5, 2025
531186d
[TNT-28] refactor: Optional 제거
fakerdeft Jan 5, 2025
e16edc5
[TNT-28] feat: 세션 인증 필터 테스트 구현
fakerdeft Jan 5, 2025
7266c03
[TNT-28] refactor: 쿠키에서 헤더 로직으로 수정
fakerdeft Jan 5, 2025
d83e7f8
[TNT-28] refactor: 쿠키에서 헤더 로직으로 수정
fakerdeft Jan 5, 2025
aa9bca4
[TNT-28] refactor: 불필요한 주석 제거
fakerdeft Jan 6, 2025
4bba1c1
[TNT-28] chore: mysql db 이름 설정
fakerdeft Jan 6, 2025
c4b227c
[TNT-28] chore: mysql db 이름 app2로 수정
fakerdeft Jan 6, 2025
1a170ed
[TNT-28] chore: 빌드 시 profile dev 추가
fakerdeft Jan 6, 2025
be6a353
[TNT-28] chore: 빌드 시 profile dev 추가
fakerdeft Jan 6, 2025
b517e65
[TNT-28] chore: 빌드 시 profile dev 삭제
fakerdeft Jan 6, 2025
7a7dd5d
[TNT-28] chore: mysql db 이름 tnt로 수정
fakerdeft Jan 6, 2025
91c6d12
Update submodule to latest version
fakerdeft Jan 6, 2025
a8a26e2
Merge remote-tracking branch 'origin/feature/TNT-28' into feature/TNT-28
fakerdeft Jan 6, 2025
71ce996
[TNT-28] chore: mysql db tnt_dev로 수정
fakerdeft Jan 6, 2025
f80c5bd
Update submodule to latest version
fakerdeft Jan 6, 2025
6b2b7a0
[TNT-28] refactor: 유효성 검사 로직 제거
fakerdeft Jan 7, 2025
5a33c7e
[TNT-28] refactor: prefix 수정
fakerdeft Jan 7, 2025
6e15931
[TNT-28] refactor: isBlank로 수정
fakerdeft Jan 7, 2025
a9efc0b
[TNT-28] refactor: throw 부분 로그 error로 수정
fakerdeft Jan 7, 2025
ee987e0
[TNT-28] refactor: 파라미터 간격 수정
fakerdeft Jan 7, 2025
86e8605
[TNT-28] refactor: 안 쓰는 메서드 제거
fakerdeft Jan 7, 2025
b8f65dc
[TNT-28] refactor: 에러 핸들링 방식 수정
fakerdeft Jan 7, 2025
08dbcf8
[TNT-28] refactor: 에러 로그 출력 방식 수정
fakerdeft Jan 7, 2025
9c176e4
[TNT-28] refactor: flush 제거
fakerdeft Jan 7, 2025
36e3566
[TNT-28] refactor: validate 메서드 private로 수정, 메서드명 수정
fakerdeft Jan 7, 2025
8495903
[TNT-28] refactor: 불필요 주석 제거
fakerdeft Jan 7, 2025
733b374
[TNT-28] refactor: 변수 위치, 개행 수정
fakerdeft Jan 7, 2025
281858d
[TNT-28] refactor: doFilter 위치 수정
fakerdeft Jan 7, 2025
c88469f
[TNT-28] refactor: 메서드명 수정
fakerdeft Jan 7, 2025
f35949e
[TNT-28] refactor: requireNonNull 적용
fakerdeft Jan 7, 2025
3335217
[TNT-28] refactor: 인증 로직 수정
fakerdeft Jan 7, 2025
6f330ff
[TNT-28] refactor: 메시지 수정
fakerdeft Jan 7, 2025
11aed26
[TNT-28] refactor: 메시지 수정
fakerdeft Jan 7, 2025
ccf892e
[TNT-28] refactor: 메시지 수정
fakerdeft Jan 7, 2025
94ee88b
[TNT-28] refactor: age int로 수정
fakerdeft Jan 7, 2025
9bf6614
[TNT-28] refactor: saveAuthentication 메서드의 파라미터명 수정
fakerdeft Jan 7, 2025
b759144
[TNT-28] refactor: isBlank 수정
fakerdeft Jan 7, 2025
1028f01
[TNT-28] refactor: 필요없는 테스트 제거
fakerdeft Jan 7, 2025
0e248b4
[TNT-28] refactor: 예외 처리 후 return 추가
fakerdeft Jan 7, 2025
39dd95b
[TNT-28] refactor: 인증 정보 저장, 서블릿 예외 테스트 추가
fakerdeft Jan 7, 2025
b7c75a7
[TNT-28] refactor: SessionValue로 클래스명 수정
fakerdeft Jan 7, 2025
2590e9b
[TNT-28] refactor: 개행 수정
fakerdeft Jan 7, 2025
33fb5aa
[TNT-28] refactor: 변수, 로그 개행 수정
fakerdeft Jan 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:

- name: MySQL Docker container for tests
run: |
sudo docker run -d -p 3306:3306 --env MYSQL_DATABASE={} --env MYSQL_ROOT_PASSWORD=root mysql:latest
sudo docker run -d -p 3306:3306 --env MYSQL_DATABASE=tnt_dev --env MYSQL_ROOT_PASSWORD=root mysql:latest

- name: Build
env:
Expand Down
7 changes: 5 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ jacocoTestCoverageVerification {
excludes = [
'*.*Application',
'*.*Config',
'*.*.*GlobalExceptionHandler'
'*.error.*'
]
}
}
Expand All @@ -126,7 +126,10 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.boot:spring-boot-starter-webflux'

// 애플 로그인을 위한 라이브러리
// TSID
implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.9.0'

// 애플 로그인 관련 라이브러리
implementation 'com.auth0:jwks-rsa:0.22.1'
implementation 'org.json:json:20231013'
implementation 'org.bouncycastle:bcprov-jdk18on:1.79'
Expand Down
75 changes: 75 additions & 0 deletions config/naver-intellij-formatter-custom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<code_scheme name="Naver-coding-convention-v1.2 custom" version="173">
<option name="LINE_SEPARATOR" value="&#10;"/>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="5"/>
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="3"/>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="javax" withSubpackages="true" static="false"/>
<package name="java" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="" withSubpackages="true" static="true"/>
</value>
</option>
<option name="RIGHT_MARGIN" value="120"/>
<option name="ENABLE_JAVADOC_FORMATTING" value="true"/>
<option name="FORMATTER_TAGS_ENABLED" value="true"/>
<JavaCodeStyleSettings>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99"/>
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1"/>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<emptyLine/>
<package name="" withSubpackages="true" static="true"/>
<emptyLine/>
<package name="java" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="javax" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="org" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="net" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="com" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="com.nhncorp" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="com.navercorp" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="com.naver" withSubpackages="true" static="false"/>
<emptyLine/>
</value>
</option>
<option name="ENABLE_JAVADOC_FORMATTING" value="false"/>
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false"/>
<option name="LINE_COMMENT_ADD_SPACE" value="true"/>
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false"/>
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="SPACE_AFTER_TYPE_CAST" value="false"/>
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
<option name="CALL_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="EXTENDS_LIST_WRAP" value="1"/>
<option name="THROWS_LIST_WRAP" value="5"/>
<option name="EXTENDS_KEYWORD_WRAP" value="1"/>
<option name="METHOD_CALL_CHAIN_WRAP" value="5"/>
<option name="BINARY_OPERATION_WRAP" value="1"/>
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
<option name="TERNARY_OPERATION_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="USE_TAB_CHARACTER" value="true"/>
</indentOptions>
</codeStyleSettings>
</code_scheme>
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
62 changes: 62 additions & 0 deletions src/main/java/com/tnt/application/auth/SessionService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.tnt.application.auth;

import static io.micrometer.common.util.StringUtils.*;
import static java.util.Objects.*;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.tnt.domain.auth.SessionValue;
import com.tnt.global.error.exception.UnauthorizedException;

import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor
public class SessionService {

static final long SESSION_DURATION = 2L * 24 * 60 * 60; // 48시간
fakerdeft marked this conversation as resolved.
Show resolved Hide resolved
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String SESSION_ID_PREFIX = "SESSION-ID ";
private final RedisTemplate<String, SessionValue> redisTemplate;

public String authenticate(HttpServletRequest request) {
String authHeader = request.getHeader(AUTHORIZATION_HEADER);
String sessionId;
Copy link
Contributor

@ymkim97 ymkim97 Jan 7, 2025

Choose a reason for hiding this comment

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

아까 초기화가 안되는 것들은 위에 두자고 했지만 그거는 로직상 어쩔 수 없을때만 하고 웬만해서는 중간에 String sessionId = authHeader.substring(SESSION_ID_PREFIX.length());가 더 좋을 것 같긴 합니다 ㅎㅎ

Copy link
Contributor Author

Choose a reason for hiding this comment

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

아하 중간에 다시 수정해서 푸쉬할게요 !!


if (isBlank(authHeader) || !authHeader.startsWith(SESSION_ID_PREFIX)) {
ymkim97 marked this conversation as resolved.
Show resolved Hide resolved
log.error("Authorization 헤더가 존재하지 않거나 올바르지 않은 형식입니다.");
throw new UnauthorizedException("인가 세션이 존재하지 않습니다.");
}
sessionId = authHeader.substring(SESSION_ID_PREFIX.length());

requireNonNull(redisTemplate.opsForValue().get(sessionId), "세션 스토리지에 세션이 존재하지 않습니다.");

return sessionId;
}

public void createSession(String memberId, HttpServletRequest request) {
SessionValue sessionValue = SessionValue.builder()
.lastAccessTime(LocalDateTime.now())
.userAgent(request.getHeader("User-Agent"))
.clientIp(request.getRemoteAddr())
.build();

redisTemplate.opsForValue().set(
memberId,
sessionValue,
SESSION_DURATION,
TimeUnit.SECONDS
);
}

public void removeSession(String sessionId) {
redisTemplate.delete(sessionId);
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/tnt/domain/auth/SessionValue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.tnt.domain.auth;

import java.time.LocalDateTime;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class SessionValue {

private LocalDateTime lastAccessTime;
private String userAgent;
private String clientIp;
}
62 changes: 62 additions & 0 deletions src/main/java/com/tnt/domain/member/Member.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.tnt.domain.member;

import java.time.LocalDateTime;

import com.tnt.global.entity.BaseTimeEntity;

import io.hypersistence.utils.hibernate.id.Tsid;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Table(name = "member")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member extends BaseTimeEntity {

@Id
@Tsid
@Column(name = "id", nullable = false, unique = true)
private Long id;

@Column(name = "social_id", nullable = false, unique = true)
ymkim97 marked this conversation as resolved.
Show resolved Hide resolved
private String socialId;

@Column(name = "email", nullable = false, length = 100)
private String email;

@Column(name = "name", nullable = false, length = 50)
private String name;

@Column(name = "age", nullable = false)
private int age;

@Column(name = "profile", nullable = false)
private String profile;

@Column(name = "deleted_at")
private LocalDateTime deletedAt;

@Enumerated(EnumType.STRING)
@Column(name = "social_type", nullable = false)
private SocialType socialType;

@Builder
public Member(Long id, String socialId, String email, String name, int age, SocialType socialType) {
this.id = id;
this.socialId = socialId;
this.email = email;
this.name = name;
this.age = age;
this.profile = "";
this.socialType = socialType;
Comment on lines +55 to +60
Copy link
Contributor

Choose a reason for hiding this comment

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

id(pk)나 int 등 primitive는 제외하고 객체들은 Objects.requireNonNull(static import)로 null 체크는 어떨까요? + 값 validation 등..
이건 상의해서 정해보죵

Copy link
Contributor Author

Choose a reason for hiding this comment

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

id(pk)나 int 등 primitive는 제외하고 객체들은 Objects.requireNonNull(static import)로 null 체크는 어떨까요? + 값 validation 등.. 이건 상의해서 정해보죵

아하 좋습니다 ! null 체크나 유효성 검사 컨벤션은 조만간 상의해봐요 !!

}
}
7 changes: 7 additions & 0 deletions src/main/java/com/tnt/domain/member/SocialType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.tnt.domain.member;

public enum SocialType {
KAKAO,
GOOGLE,
APPLE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.tnt.domain.member.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.tnt.domain.member.Member;

@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {

}
100 changes: 100 additions & 0 deletions src/main/java/com/tnt/global/auth/SessionAuthenticationFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package com.tnt.global.auth;

import java.io.IOException;
import java.util.List;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import com.tnt.application.auth.SessionService;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor
public class SessionAuthenticationFilter extends OncePerRequestFilter {

private final GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();
private final AntPathMatcher pathMatcher = new AntPathMatcher();
private final List<String> allowedUris;
private final SessionService sessionService;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String requestUri = request.getRequestURI();
String queryString = request.getQueryString();

log.info("들어온 요청 - URI: {}, Query: {}, Method: {}", requestUri, queryString != null ? queryString : "쿼리 스트링 없음",
request.getMethod());
Copy link
Contributor

Choose a reason for hiding this comment

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

log들은 로직에 섞여 보이지 않게 개행 처리로 구분해주는건 어떨까요!? 다른쪽들도 다 마찬가지 입니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

아하 좋습니다 바로 수정 들어가겠습니다 !!

if (isAllowedUri(requestUri)) {
log.info("{} 허용 URI. 세션 유효성 검사 스킵.", requestUri);
filterChain.doFilter(request, response);
return;
}

try {
checkSessionAndAuthentication(request);
} catch (RuntimeException e) {
log.error("인증 처리 중 에러 발생: ", e);
handleUnauthorizedException(response, e);
return;
}

filterChain.doFilter(request, response);
}

private boolean isAllowedUri(String requestUri) {
boolean allowed = false;

for (String pattern : allowedUris) {
if (pathMatcher.match(pattern, requestUri)) {
allowed = true;
break;
}
}
log.info("URI {} is {}allowed", requestUri, allowed ? "" : "not ");

return allowed;
}

private void checkSessionAndAuthentication(HttpServletRequest request) {
String sessionId = sessionService.authenticate(request);

saveAuthentication(Long.parseLong(sessionId));
Copy link
Contributor

Choose a reason for hiding this comment

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

여기에 sessionService.createSession()도 있어야하지 않나요!?
그리고 saveAuthentication(Long.parseLong(sessionId))의 매개변수는 memberId인데 여기는 sessionId입니다!
memberId를 넣어주도록 수정이 필요해 보여요!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

여기에 sessionService.createSession()도 있어야하지 않나요!? 그리고 saveAuthentication(Long.parseLong(sessionId))의 매개변수는 memberId인데 여기는 sessionId입니다! memberId를 넣어주도록 수정이 필요해 보여요!

createSession은 추후 개발할 회원 로그인 로직 쪽에서 사용하려고 했습니다 !!
로그인 요청(로그인 api 엔드포인트는 허용 uri) -> 회원 세션 생성
이런 플로우로 세션 생성과 인증을 구성하려고 했습니다 !
sessionId가 곧 memberId인데 변수를 만들어서 다시 넣어주도록 하겠습니다 !!

}

private void handleUnauthorizedException(HttpServletResponse response, RuntimeException exception) throws
IOException {
log.error("인증 실패: ", exception);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(exception.getMessage());
}

private void saveAuthentication(Long sessionId) {
UserDetails userDetails = User.builder()
.username(String.valueOf(sessionId))
.password("")
.roles("USER")
.build();

Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null,
authoritiesMapper.mapAuthorities(userDetails.getAuthorities()));

SecurityContextHolder.getContext().setAuthentication(authentication);
Copy link
Contributor

Choose a reason for hiding this comment

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

좋습니다~
이건 특히 중요한 부분이니 혹시라도 자동으로 ContextHolder가 비워지지 못하는 일이 없는지 고민은 같이 해봐야겠습니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

좋습니다~ 이건 특히 중요한 부분이니 혹시라도 자동으로 ContextHolder가 비워지지 못하는 일이 없는지 고민은 같이 해봐야겠습니다!

비동기 상황이 보통 그럴까요??
시큐리티 컨텍스트에 인증 정보가 남아있는 상황에 대해서 좀 더 찾아보고 오겠습니다 !!

log.info("시큐리티 컨텍스트에 인증 정보 저장 완료 - SessionId: {}", sessionId);
}
}
Loading
Loading