我在使用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方法没有按预期运行。
1条答案
按热度按时间gv8xihay1#
您可以像下面这样尝试使用MvcRequestMatcher或AntPathRequestMatcher,这取决于您需要Springmvc路径还是ant路径模式
https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/util/matcher/AntPathRequestMatcher.html