Skip to content

Commit

Permalink
Merge pull request #78 from Team-INSERT/security
Browse files Browse the repository at this point in the history
refactor(auth): spring security & redis를 커스텀 인터셉터로 변경
  • Loading branch information
jacobhboy authored Apr 12, 2024
2 parents 7f1cadc + cc0fa90 commit 0926bae
Show file tree
Hide file tree
Showing 58 changed files with 491 additions and 886 deletions.
3 changes: 0 additions & 3 deletions setting/dependencies.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
dependencies {
//default SpringBoot
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-validation'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

Expand All @@ -17,7 +15,6 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'

//test
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'com.h2database:h2'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.project.bumawiki.domain.auth.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@LoginRequired
public @interface AdminOnly {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.project.bumawiki.domain.auth.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginOrNot {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.project.bumawiki.domain.auth.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@LoginOrNot
public @interface LoginRequired {
}
29 changes: 0 additions & 29 deletions src/main/java/com/project/bumawiki/domain/auth/domain/AuthId.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.project.bumawiki.domain.auth.domain;

public record Token(
String accessToken,
String refreshToken
) {
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.project.bumawiki.domain.auth.interceptor;

import static org.springframework.http.HttpHeaders.*;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import com.project.bumawiki.domain.auth.annotation.AdminOnly;
import com.project.bumawiki.domain.auth.annotation.LoginOrNot;
import com.project.bumawiki.domain.auth.annotation.LoginRequired;
import com.project.bumawiki.domain.auth.service.implementation.AuthReader;
import com.project.bumawiki.domain.auth.service.implementation.AuthUpdater;
import com.project.bumawiki.domain.auth.util.BearerTokenExtractor;
import com.project.bumawiki.domain.auth.util.JwtParser;
import com.project.bumawiki.domain.user.domain.User;
import com.project.bumawiki.domain.user.domain.authority.Authority;
import com.project.bumawiki.domain.user.domain.repository.UserRepository;
import com.project.bumawiki.global.error.exception.BumawikiException;
import com.project.bumawiki.global.error.exception.ErrorCode;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Configuration
@RequiredArgsConstructor
public class AuthInterceptor implements HandlerInterceptor {
private final JwtParser jwtParser;
private final AuthUpdater authUpdater;
private final AuthReader authReader;
//TODO UserReader로 변경
private final UserRepository userRepository;

private static void shouldUserAdmin(User currentUser) {
if (currentUser.getAuthority() != Authority.ADMIN) {
throw new BumawikiException(ErrorCode.USER_NOT_ADMIN);
}
}

@Override
public boolean preHandle(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull Object handler
) {
if (handler instanceof HandlerMethod hm) {
if (hm.hasMethodAnnotation(LoginOrNot.class)) {
String bearer = request.getHeader(AUTHORIZATION);

if (bearer == null) {
authUpdater.updateCurrentUser(null);
} else {
String jwt = BearerTokenExtractor.extract(bearer);
Long userId = jwtParser.getIdFromJwt(jwt);

User user = userRepository.getById(userId);

authUpdater.updateCurrentUser(user);
}
}

if (hm.hasMethodAnnotation(LoginRequired.class)) {
if (authReader.getCurrentUser() == null) {
throw new BumawikiException(ErrorCode.USER_NOT_LOGIN);
}
}
if (hm.hasMethodAnnotation(AdminOnly.class)) {
User currentUser = authReader.getCurrentUser();
shouldUserAdmin(currentUser);
}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@

import java.io.IOException;

import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.project.bumawiki.domain.auth.presentation.dto.TokenResponseDto;
import com.project.bumawiki.domain.auth.service.AccessTokenRefreshService;
import com.project.bumawiki.domain.user.service.UserLoginService;
import com.project.bumawiki.domain.user.service.UserLogoutService;
import com.project.bumawiki.global.jwt.dto.TokenResponseDto;
import com.project.bumawiki.domain.auth.service.UserSignUpOrUpdateService;

import lombok.RequiredArgsConstructor;

Expand All @@ -23,22 +20,16 @@
@RestController
@RequestMapping("/api/auth")
public class AuthController {
private final UserLoginService userLoginService;
private final UserLogoutService userLogoutService;
private final UserSignUpOrUpdateService userSignUpOrUpdateService;
private final AccessTokenRefreshService accessTokenRefreshService;

@PostMapping("/oauth/bsm")
public TokenResponseDto userSignup(@RequestHeader("authCode") String authCode) throws IOException {
return ResponseEntity.ok(userLoginService.execute(authCode)).getBody();
}

@DeleteMapping("/bsm/logout")
public ResponseEntity<String> userLogout(@RequestHeader("refreshToken") String refreshToken) {
return ResponseEntity.ok(userLogoutService.execute(refreshToken));
return TokenResponseDto.from(userSignUpOrUpdateService.execute(authCode));
}

@PutMapping("/refresh/access")
public TokenResponseDto refreshAccessToken(@RequestHeader("refreshToken") String refreshToken) {
return ResponseEntity.ok(accessTokenRefreshService.execute(refreshToken)).getBody();
return TokenResponseDto.from(accessTokenRefreshService.execute(refreshToken));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.project.bumawiki.domain.auth.presentation.dto;

public record AccessTokenRequestDto(
String accessToken
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.project.bumawiki.domain.auth.presentation.dto;

public record RefreshTokenRequestDto(
String refreshToken
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.project.bumawiki.domain.auth.presentation.dto;

import com.project.bumawiki.domain.auth.domain.Token;

public record TokenResponseDto(
String accessToken,
String refreshToken
) {
public static TokenResponseDto from(Token token) {
return new TokenResponseDto(
token.accessToken(),
token.refreshToken()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.project.bumawiki.domain.auth.repository;

import org.springframework.stereotype.Repository;
import org.springframework.web.context.annotation.RequestScope;

import com.project.bumawiki.domain.user.domain.User;
import com.project.bumawiki.global.error.exception.BumawikiException;
import com.project.bumawiki.global.error.exception.ErrorCode;

@Repository
@RequestScope
public class AuthRepository {
private User currentUser;

public User getCurrentUser() {
if (currentUser == null) {
throw new BumawikiException(ErrorCode.USER_NOT_LOGIN);
}
return currentUser;
}

public User getNullableCurrentUser() {
return currentUser;
}

public void updateCurrentUser(User currentUser) {
this.currentUser = currentUser;
}
}
Loading

0 comments on commit 0926bae

Please sign in to comment.