stackoverflow
stackoverflow作为一个国外的知名网站,囊括了大量的曾经发生过的问题和正在发生的–当然是程序层面
如果你问我如何访问,其实答案非常简单,通过科学上网,然后根据提示给个邮箱注册账户登录即可使用
搬运一个springboot的奖励问题
问题
我设置了一个 springboot 应用程序并试图获得基本的用户登录设置。从我研究过的所有内容来看,拥有 @Configuration 和 @EnableWebSecurity 标记足以提醒 Spring 关于您的类覆盖其配置(使用返回 SecurityFilterChain 的 @Bean 方法)。但是,在运行该应用程序时,它仍然使用 DefaultSecurityFilterChain 并希望我使用“用户”和自动生成的密码登录,该密码已转储到控制台中。我不确定让 Spring 识别我的 SecurityConfig 我缺少什么。但是,我在运行时没有收到任何 System.out/log.info 消息(主要方法的 Hello World 除外),并且它无法识别来自 UserDetailsService 的用户。
安全配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private ArchlandsUserDetailsService userDetailsService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
System.out.println("In securityFilterChain");
http
.csrf().disable()
.authorizeHttpRequests((requests) -> requests
.requestMatchers("archlands/api/**").hasRole("USER")
.anyRequest().authenticated()
)
.formLogin((form) -> form
.loginPage("/login").permitAll()
)
.logout((logout) -> logout.permitAll())
.authenticationProvider(authenticationProvider());
return http.build();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
return authenticationProvider;
}
}
用户详情服务
@RequiredArgsConstructor
@Service
@Slf4j
public class ArchlandsUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) {
String cleanedUsername = ArchlandsInputSanitizer.clean(username);
log.info("User " + cleanedUsername + " is attempting to access the Archlands.");
System.out.println("User " + cleanedUsername + " is attempting to access the Archlands.");
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
UserDto user = userService.findById(cleanedUsername);
if (user == null) {
log.error("No user exists with user id: " + cleanedUsername);
throw new UsernameNotFoundException("No user exists with user id: " + cleanedUsername);
}
if (user.getStatus().equals("Active")) {
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
for (int i = 0; i < user.getRoles().length; i++) {
if (user.getRoles()[i].equals(Role.DM_ROLE)) {
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_DM"));
}
}
log.info("User: " + cleanedUsername + " has authorities: " + grantedAuthorities.toString());
return new User(user.getId(), user.getPassword(), grantedAuthorities);
}
}
控制台输出
解决
方案一
如果我没看错,则System.out.println("In securityFilterChain")
不会打印 in SecurityConfig。如果是这样,问题是 SecurityConfig Configuration 没有被 Spring 获取。
如果您不使用自定义*@ComponentScan -s,请检查您的主 Spring 类(用**@SpringBootApplication*注释的类)包 - 它应该至少与您的 SecurityConfig 具有相同的包级别。例如。
如果您的@SpringBootApplication 在包中:
org.dummy.app.SpringBootApp
然后安全配置应该在 org.dummy.app 包下,如:
org.dummy.app.SecurityConfig
或者喜欢:
org.dummy.app.config.SecurityConfig
方案二
看来您已经使用@Configuration
和正确地注释了您的 SecurityConfig 类@EnableWebSecurity
。但是,我可以看到filterChain
您的配置方法没有被调用,因为您在其中添加的日志消息没有被打印出来。
如果 Spring 无法检测到您的 SecurityConfig 类,就会发生这种情况,这可能是由于一些原因造成的,例如错误的包命名或错误配置的组件扫描。
以下是您可以尝试帮助 Spring 识别您的 SecurityConfig 类的一些方法:
-
@Configuration
确保您的 SecurityConfig 类位于正确的包中:默认情况下,Spring Boot 将扫描与您的主应用程序类 ( ) 在同一包中的组件(如类)@SpringBootApplication
。如果您的 SecurityConfig 类不在同一个包中,您可能需要使用@ComponentScan
或指定要扫描的其他包@SpringBootApplication(scanBasePackages = "...")
。 -
检查您的
@ComponentScan
配置:如果您在应用程序中明确配置了一个@ComponentScan
,请确保它包含您的 SecurityConfig 类所在的包。 -
检查你的导入:确保你已经为你的配置注释(
@Configuration
和@EnableWebSecurity
)导入了正确的类。这些应该分别是org.springframework.context.annotation.Configuration
和org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
。 -
确保您的应用程序没有使用 Spring Security 自动配置:如果 Spring Boot 检测到您没有在应用程序中提供任何安全配置,它将自动为您配置基本的安全设置。您可以通过将
spring.autoconfigure.exclude
属性添加到 application.properties 或 application.yml 文件来禁用此功能,如下所示:spring.autoconfigure.exclude = org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
希望这个建议有效。
方案三
您可以在注释上方的SecurityConfig类中添加@Order(SecurityProperties.BASIC_AUTH_ORDER)
注释。因此,您的安全配置的优先级高于默认配置。此外,您可能会考虑向 ArchlandsUserDetailsService添加注释,以确保它已正确注册。@Configuration``@Bean
总结
可以看到的是,在stackoverflow不仅有解决问题的方案,而且有很多套,甚至如果是一个日期靠前的问题,你还可以和别人进行沟通
国内的csdn做的不错,但是任然有些东西确实西方更好,比如更多更优质的程序员,更多个原视开发者,更多的大佬