Skip to content

Commit

Permalink
Merge pull request #198 from kakao-tech-campus-2nd-step3/feature/ISSU…
Browse files Browse the repository at this point in the history
…E-175

시큐리티 최종
  • Loading branch information
amm0124 authored Nov 14, 2024
2 parents 7e79a19 + d061297 commit 7f525eb
Show file tree
Hide file tree
Showing 23 changed files with 314 additions and 262 deletions.
115 changes: 66 additions & 49 deletions src/main/java/poomasi/domain/auth/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package poomasi.domain.auth.config;

import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -15,22 +13,23 @@
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import poomasi.domain.auth.security.filter.JwtLogoutFilter;
import poomasi.domain.auth.security.filter.CustomUsernamePasswordAuthenticationFilter;
import poomasi.domain.auth.security.filter.JwtAuthenticationFilter;
import poomasi.domain.auth.security.handler.CustomSuccessHandler;
import poomasi.domain.auth.security.handler.OAuth2FailureHandler;
import poomasi.domain.auth.security.handler.OAuth2SuccessHandler;
import poomasi.domain.auth.security.userdetail.OAuth2UserDetailServiceImpl;
import poomasi.domain.auth.security.userdetail.UserDetailsServiceImpl;
import poomasi.domain.auth.token.blacklist.service.BlacklistJpaService;
import poomasi.domain.auth.token.refreshtoken.service.RefreshTokenService;
import poomasi.domain.auth.token.util.JwtUtil;

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


@AllArgsConstructor
@Configuration
Expand All @@ -41,26 +40,37 @@ public class SecurityConfig {
private final AuthenticationConfiguration authenticationConfiguration;
private final JwtUtil jwtUtil;
private final MvcRequestMatcher.Builder mvc;
private final CustomSuccessHandler customSuccessHandler;
private final OAuth2SuccessHandler oAuth2SuccessHandler;
private final OAuth2FailureHandler oAuth2FailureHandler;
private final UserDetailsServiceImpl userDetailsService;
private final CorsConfigurationSource corsConfigurationSource;
private final BlacklistJpaService blacklistService;
private final RefreshTokenService refreshTokenService;

@Autowired
private OAuth2UserDetailServiceImpl oAuth2UserDetailServiceImpl;



/*@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring()
.requestMatchers("/error");
}
*/
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
return configuration.getAuthenticationManager();
}

@Description("순서 : Oauth2 -> jwt -> login -> logout")
@Description("순서 : logout -> Oauth2 -> jwt -> login ")
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

//form login disable
//기본 폼로그인 비활성화
http.formLogin(AbstractHttpConfigurer::disable);

//basic login disable
//http basic 비활성화
http.httpBasic(AbstractHttpConfigurer::disable);

//csrf 해제
Expand All @@ -74,58 +84,65 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
http.sessionManagement((session) -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

//기본 로그아웃 해제
//기본 로그아웃 비활성화
http.logout(AbstractHttpConfigurer::disable);


// 기본 경로 및 테스트 경로
http.authorizeHttpRequests((authorize) -> authorize


// 기본 경로 및 테스트 경로
// 인증 및 인가가 필요한 부분을 "authenticated"로 표시해주세요

//건호 api
.requestMatchers("/oauth2/authentication/kakao").authenticated()
.requestMatchers("api/order/**").authenticated()
.requestMatchers(HttpMethod.POST, "api/logout").authenticated()

//진택 api
.requestMatchers(HttpMethod.POST, "/api/member/update/**").authenticated()
.requestMatchers(HttpMethod.GET, "/api/member/**").authenticated()
.requestMatchers(HttpMethod.POST, "/api/reiusse").authenticated()

//지민 api
.requestMatchers(HttpMethod.GET, "/api/image/**").permitAll()

//풍헌 api

/*.requestMatchers(HttpMethod.POST, "/api/farm/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/product/**").permitAll()
.requestMatchers(HttpMethod.GET, "/api/review/**").permitAll()
.requestMatchers(HttpMethod.GET, "/health").permitAll()
.requestMatchers(HttpMethod.GET, "/api/image/**").permitAll()
.requestMatchers("/api/farm/**", "/api/member/sign-up", "/api/login", "api/reissue", "api/payment/**", "api/order/**", "api/reservation/**", "/api/v1/farmer/reservations", "/api/v1/biz/farmer/**").permitAll()
.requestMatchers("/api/member/sign-up", "/api/login", "/api/reissue", "/api/payment/**", "/api/order/**", "api/reservation/**", "/api/v1/farmer/reservations").permitAll()
.requestMatchers("/api/need-auth/**").authenticated()
.anyRequest().
authenticated()
.requestMatchers("/api/logout").permitAll()*/
.anyRequest().permitAll()
);


//endpoint : {domain}/oauth2/authentication/kakao
// http
// .oauth2Login((oauth2) -> oauth2
// .userInfoEndpoint((userInfoEndpointConfig) -> userInfoEndpointConfig
// .userService(oAuth2UserDetailServiceImpl))
// .successHandler(customSuccessHandler)
// );

//oauth2 filter
http
.oauth2Login((oauth2) -> oauth2
.userInfoEndpoint((userInfoEndpointConfig) -> userInfoEndpointConfig
.userService(oAuth2UserDetailServiceImpl)
)
.successHandler(oAuth2SuccessHandler)
.failureHandler(oAuth2FailureHandler)
);

//username password filter
CustomUsernamePasswordAuthenticationFilter customUsernameFilter =
new CustomUsernamePasswordAuthenticationFilter(authenticationManager(authenticationConfiguration), jwtUtil);
new CustomUsernamePasswordAuthenticationFilter(authenticationManager(authenticationConfiguration), jwtUtil, refreshTokenService);
customUsernameFilter.setFilterProcessesUrl("/api/login");

http.addFilterAt(customUsernameFilter, UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(new JwtAuthenticationFilter(jwtUtil, userDetailsService), UsernamePasswordAuthenticationFilter.class);

/*
로그아웃 필터 등록하기
LogoutHandler[] handlers = {
new CookieClearingLogoutHandler(),
new ClearAuthenticationHandler()
};
CustomLogoutFilter customLogoutFilter = new CustomLogoutFilter(jwtUtil, new CustomLogoutSuccessHandler(), handlers);
customLogoutFilter.setFilterProcessesUrl("/api/logout");
customLogoutFilter.
http.addFilterAt(customLogoutFilter, LogoutFilter.class);
http.logout( (logout) ->
logout.
logoutSuccessHandler(new CustomLogoutSuccessHandler())
.addLogoutHandler(new CookieClearingLogoutHandler())
.addLogoutHandler(new ClearAuthenticationHandler())
);
*/

//http.addFilterAfter(customLogoutFilter, JwtAuthenticationFilter.class);
//jwt filter
http.addFilterAfter(new JwtAuthenticationFilter(jwtUtil, userDetailsService, blacklistService),
OAuth2LoginAuthenticationFilter.class);

//logout filter
JwtLogoutFilter customLogoutFilter = new JwtLogoutFilter(jwtUtil, blacklistService, refreshTokenService);
http.addFilterAfter(customLogoutFilter, JwtAuthenticationFilter.class);

return http.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ public String Test(){
return "Success";
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ public String Test(){
return "SUCCESS";
}

}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import poomasi.domain.auth.security.userdetail.UserDetailsImpl;
import poomasi.domain.auth.token.refreshtoken.service.RefreshTokenService;
import poomasi.domain.auth.token.util.JwtUtil;


Expand All @@ -30,15 +31,16 @@ public class CustomUsernamePasswordAuthenticationFilter extends UsernamePassword

private final AuthenticationManager authenticationManager;
private final JwtUtil jwtUtil;
private final RefreshTokenService refreshTokenService;

@Description("인증 시도 메서드")
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException{

log.info("email - password 기반으로 인증을 시도 합니다 : CustomUsernamePasswordAuthenticationFilter");
ObjectMapper loginRequestMapper = new ObjectMapper();
String email;
String password;
String email = null;
String password = null;

try {
BufferedReader reader = request.getReader();
Expand All @@ -59,20 +61,21 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ
@Description("로그인 성공 시, accessToken과 refreshToken 발급")
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
UserDetailsImpl customUserDetails = (UserDetailsImpl) authentication.getPrincipal();
String username = customUserDetails.getUsername();
String role = customUserDetails.getAuthority();
Long memberId = customUserDetails.getMember().getId();

String accessToken = jwtUtil.generateAccessTokenById(memberId);
String refreshToken = jwtUtil.generateRefreshTokenById(memberId);

log.info("usename password 기반 로그인 성공 . cookie에 토큰을 넣어 발급합니다.");
response.setHeader("access", accessToken);
log.info("username password 기반 로그인 성공 . cookie에 토큰을 넣어 발급합니다.");
response.addCookie(createCookie("refresh", refreshToken));
response.setStatus(HttpStatus.OK.value());

// 나중에 주석 해야 함
PrintWriter out = response.getWriter();
out.println("access : " + accessToken + ", refresh : " + refreshToken);
out.close();
refreshTokenService.putRefreshToken(refreshToken, memberId);

response.setContentType("application/json"); // Content-Type 설정
response.getWriter().write("{\"access\": \"" + accessToken + "\", \"refresh\": \"" + refreshToken + "\"}");
}

@Override
Expand Down
Loading

0 comments on commit 7f525eb

Please sign in to comment.