springboot 3.1.3 自定义过滤器扩展 AbstractAuthenticationProcessingFilter 的问题

问题描述 投票:0回答:1

所以我观察到,当我尝试在安全链中使用自定义过滤器时,我没有获得会话 cookie...为什么我要这样做?因为我想以 JSON 格式发送用户名和密码,而不是在查询字符串中...

我基于此:

https://ckinan.com/blog/spring-security-credentials-from-json-request/

我查了一下:

Spring security-以 json 形式发送凭证,而不是在 Rest 服务中发送常规形式

我的自定义过滤器:

public class CustomFilter extends AbstractAuthenticationProcessingFilter {
    protected CustomFilter() {
        super(new AntPathRequestMatcher("/login", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(
            HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        String username, password;

        try {
            Map<String, String> requestMap = new ObjectMapper().readValue(request.getInputStream(), Map.class);
            username = requestMap.get("username");
            password = requestMap.get("password");
        } catch (IOException e) {
            throw new AuthenticationServiceException(e.getMessage(), e);
        }

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                username, password);

        return this.getAuthenticationManager().authenticate(authRequest);
    }
}

我的安全配置:

    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        CustomFilter mupaf = new CustomFilter();
        mupaf.setAuthenticationManager(authenticationManager(authenticationManagerBuilder));

        http.csrf(AbstractHttpConfigurer::disable)
                .sessionManagement((sessionManagement) ->
                        sessionManagement.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                                .sessionFixation().changeSessionId())
                .authorizeHttpRequests((authorizeHttpRequests) ->
                        authorizeHttpRequests.requestMatchers("/index").permitAll()
                                .requestMatchers("/login").permitAll()
                                .anyRequest().authenticated()
                ).addFilterAt(mupaf, UsernamePasswordAuthenticationFilter.class
                )
                .logout((logout) ->
                        logout.deleteCookies("remove")
                                .invalidateHttpSession(false)
                                .logoutSuccessUrl("/index")
                );
        return http.build();
    }

服务员回答:

❯ curl -X POST http://localhost:8080/login -H 'Content-Type: application/json' -d '{"username":"admin","password":"pass"}' -i
HTTP/1.1 302
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Location: http://localhost:8080/
Content-Length: 0
Date: Sun, 08 Oct 2023 21:39:46 GMT

当我禁用过滤器响应时:

❯ curl -X POST http://localhost:8080/login\?username\=ADMIN\&password\=pass -i
HTTP/1.1 302
Set-Cookie: SESSION=40E7A645752D0AACFA52C79D5DEA10EF; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Location: http://localhost:8080/
Content-Length: 0
Date: Sun, 08 Oct 2023 21:41:20 GMT

安全配置看起来像这样:

    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
                .sessionManagement((sessionManagement) ->
                        sessionManagement.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                                .sessionFixation().changeSessionId())
                .authorizeHttpRequests((authorizeHttpRequests) ->
                        authorizeHttpRequests.requestMatchers("/index").permitAll()
                                .requestMatchers("/login").permitAll()
                                .anyRequest().authenticated()
                ).formLogin((formLogin) ->
                        formLogin.defaultSuccessUrl("/success", true)
                                .failureHandler(customLoginFailureHandler)
                                .successHandler(customLoginSuccessHandler)
                )
                .logout((logout) ->
                        logout.deleteCookies("remove")
                                .invalidateHttpSession(false)
                                .logoutSuccessUrl("/index")
                );
        return http.build();
    }
java spring spring-boot spring-security spring-session
1个回答
0
投票
    CustomFilter mupaf = new CustomFilter();
    mupaf.setAuthenticationManager(authConfig.getAuthenticationManager());
    SecurityContextRepository securityContextRepository = http.getSharedObject(SecurityContextRepository.class);
    if (securityContextRepository == null) {
        mupaf.setSecurityContextRepository(new DelegatingSecurityContextRepository(new RequestAttributeSecurityContextRepository(), new HttpSessionSecurityContextRepository()));
    }
© www.soinside.com 2019 - 2024. All rights reserved.