Skip to content

Commit

Permalink
Merge pull request #48 from DSM-Repo/security
Browse files Browse the repository at this point in the history
pr :: security 설정
  • Loading branch information
dkflfkd53 authored Aug 8, 2024
2 parents 0fc1419 + 4ed6727 commit f21cb71
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import com.example.whopper.domain.document.dto.response.FullDocumentResponse;
import com.example.whopper.domain.document.dto.response.ReleasedDocumentResponse;
import com.example.whopper.domain.document.dto.response.SearchDocumentResponse;
import com.example.whopper.global.annotation.OnlyStudent;
import com.example.whopper.global.annotation.OnlyTeacher;
import com.example.whopper.global.utils.DataResponseInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
Expand All @@ -30,30 +32,35 @@ public class DocumentController {
private final ReleaseDocumentUseCase releaseDocumentUseCase;
private final CancelReleaseDocumentUseCase cancelReleaseDocumentUseCase;

@OnlyTeacher
@ResponseStatus(HttpStatus.NO_CONTENT)
@PostMapping("/release/{documentId}")
public void release(@PathVariable String documentId) {
releaseDocumentUseCase.release(documentId);
}

@OnlyTeacher
@ResponseStatus(HttpStatus.NO_CONTENT)
@PostMapping("/release/cancel/{documentId}")
public void cancelRelease(@PathVariable String documentId) {
cancelReleaseDocumentUseCase.cancel(documentId);
}

@OnlyStudent
@ResponseStatus(HttpStatus.NO_CONTENT)
@PatchMapping("/submit")
public void submit() {
submitMyDocumentUseCase.submit();
}

@OnlyStudent
@ResponseStatus(HttpStatus.NO_CONTENT)
@PatchMapping("/submit/cancel")
public void cancelSubmit() {
cancelSubmitMyDocumentUseCase.cancel();
}

@OnlyTeacher
@GetMapping("/student")
public DataResponseInfo<SearchDocumentResponse> search(@ModelAttribute SearchDocumentRequest request) {
return findDocumentUseCase.searchDocument(request);
Expand All @@ -69,50 +76,59 @@ public FullDocumentResponse findReleasedDocument(@PathVariable String documentId
return findDocumentUseCase.findReleasedDocument(documentId);
}

@OnlyTeacher
@GetMapping("/student/{documentId}")
public FullDocumentResponse getSubmittedDocument(@PathVariable String documentId) {
return findDocumentUseCase.getSubmittedDocument(documentId);
}

@OnlyStudent
@GetMapping("/completion")
public CompletionElementLevel getCompletionLevel() {
return findDocumentUseCase.getCurrentStudentDocumentCompletionLevel();
}

@OnlyStudent
@GetMapping
public DocumentResponse getIntroduceRecentlySharedDocuments() {
return findDocumentUseCase.getIntroduceRecentlySharedDocuments();
}

@OnlyStudent
@GetMapping("/detail")
public FullDocumentResponse getCurrentDocument() {
return findDocumentUseCase.getCurrentStudentDocument();
}

@OnlyStudent
@ResponseStatus(HttpStatus.NO_CONTENT)
@PatchMapping("/writer-info")
public void updateWriterInfo(@RequestBody UpdateWriterInfoRequest request) {
updateWriterInfoUseCase.update(request);
}

@OnlyStudent
@ResponseStatus(HttpStatus.NO_CONTENT)
@PatchMapping("/introduce")
public void updateIntroduce(@RequestBody IntroduceElement request) {
updateIntroduceUseCase.update(request);
}

@OnlyStudent
@ResponseStatus(HttpStatus.NO_CONTENT)
@PatchMapping("/project")
public void updateProjectList(@RequestPart("projectList") UpdateListRequest<ProjectElement> request) {
updateProjectListUseCase.update(request.list());
}

@OnlyStudent
@ResponseStatus(HttpStatus.NO_CONTENT)
@PatchMapping("/achievement")
public void updateAchievementList(@RequestBody UpdateListRequest<AchievementElement> request) {
updateAchievementListUseCase.update(request.list());
}

@OnlyStudent
@ResponseStatus(HttpStatus.NO_CONTENT)
@PatchMapping("/activity")
public void updateActivityList(@RequestBody UpdateListRequest<ActivityElement> request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.example.whopper.domain.feedback.application.usecase.UpdateFeedbackUseCase;
import com.example.whopper.domain.feedback.dto.DeleteFeedbackRequest;
import com.example.whopper.domain.feedback.dto.FeedbackRequest;
import com.example.whopper.global.annotation.OnlyTeacher;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping;
Expand All @@ -23,16 +24,19 @@ public class FeedbackController {

private final DeleteFeedbackUseCase deleteFeedbackUseCase;

@OnlyTeacher
@PostMapping
public void addFeedback(FeedbackRequest request) {
addFeedbackUseCase.addFeedback(request);
}

@OnlyTeacher
@PatchMapping
public void updateFeedback(FeedbackRequest request) {
updateFeedbackUseCase.updateFeedback(request);
}

@OnlyTeacher
@DeleteMapping
public void deleteFeedback(DeleteFeedbackRequest request) {
deleteFeedbackUseCase.deleteFeedback(request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.example.whopper.domain.file.application.usecase.SaveImageUseCase;
import com.example.whopper.domain.file.dto.response.ImagePathResponse;
import com.example.whopper.domain.file.type.ImageType;
import com.example.whopper.global.annotation.OnlyStudent;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -19,6 +20,7 @@ public class FileController {

private final SaveImageUseCase saveImageUseCase;

@OnlyStudent
@PostMapping(value = "/image", consumes = {
MediaType.MULTIPART_FORM_DATA_VALUE
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.example.whopper.domain.major.application.usecase.DeleteMajorUseCase;
import com.example.whopper.domain.major.application.usecase.FindMajorUseCase;
import com.example.whopper.domain.major.domain.MajorEntity;
import com.example.whopper.global.annotation.OnlyTeacher;
import com.example.whopper.global.utils.DataResponseInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
Expand All @@ -18,6 +19,7 @@ public class MajorController {
private final FindMajorUseCase findMajorUseCase;
private final DeleteMajorUseCase deleteMajorUseCase;

@OnlyTeacher
@PostMapping
public void add(@RequestBody AddMajorRequest request) {
addMajorUseCase.add(request.majors());
Expand All @@ -28,6 +30,7 @@ public DataResponseInfo<MajorEntity> findAll() {
return findMajorUseCase.findAll();
}

@OnlyTeacher
@DeleteMapping("/{majorId}")
public void delete(@PathVariable String majorId) {
deleteMajorUseCase.delete(majorId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.example.whopper.domain.student.application.usecase.GetCurrentUserInfoUseCase;
import com.example.whopper.domain.student.dto.GetCurrentUserInfoResponse;
import com.example.whopper.global.annotation.OnlyStudent;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -12,7 +13,8 @@
@RequiredArgsConstructor
public class StudentController {
private final GetCurrentUserInfoUseCase getCurrentUserInfoUseCase;


@OnlyStudent
@GetMapping("/current/info")
public GetCurrentUserInfoResponse getCurrentUserInfoResponse() {
return getCurrentUserInfoUseCase.get();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.whopper.global.annotation;

import org.springframework.security.access.prepost.PreAuthorize;

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)
@PreAuthorize("hasRole('STUDENT')")
public @interface OnlyStudent {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.whopper.global.annotation;

import org.springframework.security.access.prepost.PreAuthorize;

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)
@PreAuthorize("hasRole('TEACHER')")
public @interface OnlyTeacher {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

import com.example.whopper.global.security.jwt.JwtTokenProvider;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletResponse;
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.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.configurers.AbstractHttpConfigurer;
Expand All @@ -19,17 +23,22 @@
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
@Configuration
public class SecurityConfig {

private final JwtTokenProvider jwtTokenProvider;

private final ObjectMapper objectMapper;

@Value("${app.cors.allow-hosts}")
private String allowHosts;

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
Expand All @@ -41,19 +50,25 @@ protected SecurityFilterChain configure(HttpSecurity httpSecurity) throws Except
httpSecurity
.csrf(AbstractHttpConfigurer::disable)

.cors(cors -> cors
.configurationSource(corsConfigurationSource())
)
.cors(cors -> cors.configurationSource(corsConfigurationSource()))

.headers(headers -> headers
.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin
)
.frameOptions(HeadersConfigurer.FrameOptionsConfig::deny)
.xssProtection(HeadersConfigurer.XXssConfig::disable)
.contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self'; frame-ancestors 'none';"))
)

.sessionManagement(sessionManagement -> sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)

.exceptionHandling(exceptionHandling -> exceptionHandling
.authenticationEntryPoint((request, response, authException) -> response
.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"))
.accessDeniedHandler((request, response, accessDeniedException) -> response
.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"))
)

.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/auth/**").permitAll()
.anyRequest().authenticated()
Expand All @@ -69,10 +84,11 @@ protected SecurityFilterChain configure(HttpSecurity httpSecurity) throws Except
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();

configuration.setAllowedOrigins(List.of("*")); // 모든 도메인 허용
configuration.setAllowedMethods(Arrays.asList( "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")); // HTTP 메서드 허용
configuration.setAllowedOrigins(List.of(allowHosts.split(",")));
configuration.setAllowedMethods(List.of("OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")); // HTTP 메서드 허용
configuration.setAllowCredentials(false);
configuration.addAllowedHeader("*"); // 모든 헤더 허용
configuration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
configuration.setExposedHeaders(Collections.singletonList("Authorization"));

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration); // 모든 경로에 대해 위에서 설정한 CORS 설정 적용
Expand Down
5 changes: 4 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,7 @@ server:
servlet:
context-path: /whopper
port: 8080


app:
cors:
allow-hosts: ${ALLOW_HOSTS}

0 comments on commit f21cb71

Please sign in to comment.