Spring Security Spring安全错误:“UnsatisfiedDependencyException”,带有关于“setFilterChains”的消息

6tdlim6h  于 2023-10-20  发布在  Spring
关注(0)|答案(1)|浏览(282)

我在使用Spring Security时遇到了一个问题,并且无法解决它。我得到的错误消息是:org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChains' parameter 0: Error creating bean with name 'configureSecurity' defined in class path resource [com/project/CarDB/Config/SecurityConfig.class]: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'configureSecurity' threw exception with message: This method cannot decide whether these patterns are Spring MVC patterns or not. If this endpoint is a Spring MVC endpoint, please use requestMatchers(MvcRequestMatcher); otherwise, please use requestMatchers(AntPathRequestMatcher).下面是SecurityConfig类的一部分,我在其中定义了安全配置:

package com.project.CarDB.Config;

import com.project.CarDB.service.UserDetailServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
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.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    @Autowired
    UserDetailServiceImpl userDetailsService;
    @Bean
    public UserDetailsService userDetailsService (BCryptPasswordEncoder bCryptPasswordEncoder){
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();

        manager.createUser(
                User.withUsername("user").password(bCryptPasswordEncoder.encode("userPass")).roles("USER").build()
        );

        manager.createUser(
                User.withUsername("admin").password(bCryptPasswordEncoder.encode("adminPass")).roles("ADMIN").build()
        );

        return manager;
    }

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

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }

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

    @Bean
    public SecurityFilterChain configureSecurity(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeHttpRequests(authorizeRequests -> authorizeRequests
                        .requestMatchers(HttpMethod.POST, "/login").permitAll()  // Use mvcMatchers for Spring MVC patterns
                        .anyRequest().authenticated()
                );

        return http.build();
    }


}

我相信这个错误与configureSecurity方法有关,但我不确定如何修复它。有人可以帮助我了解导致此错误的原因以及如何解决它吗?在此先谢谢您!
(其他代码片段,如LoginController和JwtService,在最初的文章中提供了上下文。

package com.project.CarDB.web;

import com.project.CarDB.Domain.Account.AccountCredentials;
import com.project.CarDB.service.JwtService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoginController {

    @Autowired
    JwtService jwtService;

    @Autowired AuthenticationManager authenticationManager;

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ResponseEntity<?> getToken (@RequestBody AccountCredentials accountCredentials){
        UsernamePasswordAuthenticationToken credentials = new UsernamePasswordAuthenticationToken(accountCredentials.getUserName(), accountCredentials.getPassword());

        Authentication authentication = authenticationManager.authenticate(credentials);

        // GENERATE TOKENS
        String jwts = jwtService.getToken(authentication.getName());

        //BUILD RESPONSE WITH THE GENERATED TOKEN
        return ResponseEntity.ok()
                .header(HttpHeaders.AUTHORIZATION, "BEARER " + jwts)
                .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "Authorization")
                .build();
    }
}
package com.project.CarDB.service;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Component
public class JwtService {

    static final long EXPIRATIONTIME = 86400000; // 1 day in ms
    static final String PREFIX = "Bearer";
    static final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

    public String getToken(String username) {
        String token = Jwts.builder()
                .setSubject(username)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                .signWith(key)
                .compact();
        return token;
    }

    public String getAuthUser(HttpServletRequest request) {
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);

        if (token != null) {
            String user = Jwts.parserBuilder()
                    .setSigningKey(key)
                    .build()
                    .parseClaimsJws(token.replace(PREFIX, ""))
                    .getBody()
                    .getSubject();

            if (user != null)
                return user;
        }

        return null;
    }

}

我尝试修改configureSecurity方法和代码中的其他方法,但在寻找解决方案一天之后,我放弃了。如果我删除SecurityFilterChain,我的应用程序运行时不会出现错误。
我进行了进一步的调查,并注意到只有当我用途:http.authorizeHttpRequests().requestMatchers(HttpMethod.POST, "/login").permitAll();,任何形式的.authorizeHttpRequests().requestMatchers("")授权都无法工作。
然而,当我写:

http.csrf().disable().cors().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

http.formLogin().and().httpBasic();
return http.build();

我的应用程序运行,但我在LoginController中使用的POST方法没有按预期运行。

gv8xihay

gv8xihay1#

您可以像下面这样尝试使用MvcRequestMatcher或AntPathRequestMatcher,这取决于您需要Springmvc路径还是ant路径模式

.authorizeHttpRequests(authorize -> authorize
                        .requestMatchers(new AntPathRequestMatcher("/login", "POST")).permitAll()
                        .anyRequest().authenticated()
                )

https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/util/matcher/AntPathRequestMatcher.html

相关问题