使用Spring Security中的SecurityFilterChain限制对端点的访问

3mpgtkmj  于 2023-10-20  发布在  Spring
关注(0)|答案(1)|浏览(152)

如何只允许hello端点允许授权(给予默认登录屏幕)和再见端点我应该看到401/403错误。
我使用的是Sping Boot v 2.7.1
当我点击http://localhost:8080/bye时,我应该无法调用它。
MySecurityConfig.java

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
public class MySecurityConfig {

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.formLogin();
        // http.httpBasic();
        http.authorizeRequests().antMatchers("/hello").authenticated();
        return http.build();
    }

//    @Bean
//    public UserDetailsService userDetailsService(){
//        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
//        UserDetails userDetails = User.withUsername("john")
//                .password(passwordEncoder().encode("12345")).authorities("READ").build();
//        userDetailsManager.createUser(userDetails);
//        return userDetailsManager;
//    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

HelloController.java

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello from Spring Security";
    }
    
    
    @GetMapping("/bye")
    public String bye() {
        return "Bye";
    }
}

AuthenticationProvider.java

@Component
public class MyAuthenticationProvider implements AuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        if ("john".equals(username) && "12345".equals(password)) {
            return new UsernamePasswordAuthenticationToken(username, password, Arrays.asList());
        } else {
            throw new BadCredentialsException("Invalid Username or password");
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
ffscu2ro

ffscu2ro1#

因为/bye没有被任何authorizeRequests()定义,并且任何没有这样的授权规则的URL意味着不需要对其进行任何授权检查,因此它总是可以被访问。
您必须通过以下方式显式配置规则以阻止对其的任何访问:

@Bean
 SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.formLogin();
        http.authorizeRequests()
           .antMatchers("/hello").authenticated()
           .antMatchers("/bye").denyAll();
        return http.build();
 }

请注意,除了/hello/bye之外的所有其他URL也可以访问。因此,一个好的策略是,我们通常会在最后添加一个规则来阻止对所有剩余URL的所有访问,以提高安全性:

@Bean
 SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.formLogin();
        http.authorizeRequests()
           .antMatchers("/hello").authenticated()
           .antMatchers("/bye").denyAll()
           .anyRequest().denyAll();
        return http.build();
 }

相关问题