강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của potatomango
potatomango

câu hỏi đã được viết

Ứng dụng kiến trúc microservice (MSA) phát triển với Spring Cloud

Thêm AuthenticationFilter

Spring Security 최신버전(Spring Boot 3.X.X 대)의 WebSecurity 설정 공유드립니다.

Viết

·

12K

·

Đã chỉnh sửa

18

최신버전으로 진행하다보니 막혔었는데요. 구글링, ChatGPT 등을 통해서 동작하는 코드 공유드립니다.

정확한 구현은 아닐 수 있겠지만, 강의를 진행하는 데는 문제 없는 것 같습니다. 참고만 부탁드려요~

 

package com.example.userservice.security;

import com.example.userservice.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.IpAddressMatcher;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurity {

    private final UserService userService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    private final ObjectPostProcessor<Object> objectPostProcessor;

    private static final String[] WHITE_LIST = {
            "/users/**",
            "/",
            "/**"
    };

    @Bean
    protected SecurityFilterChain config(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.headers().frameOptions().disable();
        http.authorizeHttpRequests(authorize -> {
                    try {
                        authorize
                                .requestMatchers(WHITE_LIST).permitAll()
                                .requestMatchers(PathRequest.toH2Console()).permitAll()
                                .requestMatchers(new IpAddressMatcher("127.0.0.1")).permitAll()
                                .and()
                                .addFilter(getAuthenticationFilter());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
        );
        return http.build();
    }

    public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
        return auth.build();
    }

    private AuthenticationFilter getAuthenticationFilter() throws Exception {
        AuthenticationFilter authenticationFilter = new AuthenticationFilter();
        AuthenticationManagerBuilder builder = new AuthenticationManagerBuilder(objectPostProcessor);
        authenticationFilter.setAuthenticationManager(authenticationManager(builder));
        return authenticationFilter;
    }

}

 

이렇게 하시고 중요한 것이, Login Form을 사용하지 않기 때문에 AuthenticationFilter 클래스의 Override 메소드 중 successfulAuthentication 메소드 내부에super.successfulAuthentication(request, response, chain, authResult);

코드가 작성되어 있다면, 아래처럼 제거 또는 주석 처리를 꼭 해야 합니다! (다른 질문 글에서 발견하였습니다, 공유 감사드립니다.)

하지 않은 경우 에러가 발생하며 login 요청이 제대로 동작하지 않습니다.

 

package com.example.userservice.security;

import com.example.userservice.vo.RequestLogin;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;
import java.util.ArrayList;

public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {
        try {
            RequestLogin creds = new ObjectMapper().readValue(request.getInputStream(), RequestLogin.class);
            return getAuthenticationManager().authenticate(
                    new UsernamePasswordAuthenticationToken(
                            creds.getEmail(),
                            creds.getPassword(),
                            new ArrayList<>()
                    )
            );
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) throws IOException, ServletException {
        //super.successfulAuthentication(request, response, chain, authResult);
    }
}
spring-bootspring-cloudspring-security최신버전

Câu trả lời 5

2

도움 감사합니다 ^^

2

Dowon Lee님의 프로필 이미지
Dowon Lee
Người chia sẻ kiến thức

안녕하세요, 이도원입니다.

공유 감사드립니다.

강의를 시작한지 2년정도 되어 가고 있습니다. 강의 업데이트를 준비 중인데, 해당 부분도 참고하겠습니다.

감사합니다.

potatomango님의 프로필 이미지
potatomango
Người đặt câu hỏi

저야말로 좋은 지식 공유해주셔서 감사드립니다.

0

감사합니다!

0

하루종일 순환참조부터 오만 시달림 당했는데 감사합니다.. 다음부턴 맘편히 버전 맞춰야겠네요 ㅠ. 감사합니다

0

감사합니다!!

Hình ảnh hồ sơ của potatomango
potatomango

câu hỏi đã được viết

Đặt câu hỏi