@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(AuthenticationController authenticationController,
AuthorizationController authorizationController,
AuthenticationProvider authenticationProvider) {
return args -> {
Spectator spectator = new Spectator("userdemo", "1234");
Player player = new Player("Khvicha", "Kvaratskhelia"); player.setId(1L);
Map<String, String> credentials = new HashMap<>();
credentials.put("username", spectator.getUsername());
credentials.put("password", spectator.getPassword());
authenticationController.register(credentials);
System.out.println(credentials);
Authentication authentication = authenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(spectator.getUsername(), spectator.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
authorizationController.addNewPlayer(player);
};
}
}
首先,我注册一个用户,然后在调用控制器方法之前,我对用户进行身份验证。此时玩家就添加成功了。但当我尝试对邮递员做同样的事情时,我失败了。
以下是我的安全配置。我不使用
WebSecurityConfigurerAdapter
或 JWT 身份验证。
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
private static final String SPECTATOR = Role.SPECTATOR.name();
private static final String COACH = Role.COACH.name();
private static final String ADMIN = Role.ADMIN.name();
private static final String[] WHITE_LIST = {
"/api/v1/users/auth/**",
};
private final AuthenticationProvider authProvider;
@Autowired
public SecurityConfiguration(AuthenticationProvider authProvider) {
this.authProvider = authProvider;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/v1/users/auth/**").permitAll()
.requestMatchers("/api/v1/home/players/create").hasAuthority(SPECTATOR)
.anyRequest().authenticated())
.sessionManagement(session -> session.sessionCreationPolicy(STATELESS))
.authenticationProvider(authProvider);
return http.build();
}
}
我尝试添加基于表单的身份验证
.formLogin(form -> form
.loginPage("/login")
.loginProcessingUrl("/api/v1/users/auth/login")
.defaultSuccessUrl("/homepage", true)
.failureUrl("/login?error=true"));
但是也没有成功。即使我确实输入了正确的凭据,我也遇到了无限重定向循环或 403 错误。
关于添加表单登录,您走在正确的轨道上,尽管考虑到您正在发布 API,我认为这可能不是您想要的。
如果您不使用 JWT,那么还有其他 API 身份验证选项,例如 HTTP Basic。考虑以下替代设置:
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.ignoreRequestMatchers(new RequestHeaderRequestMatcher("Postman-Token")))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/v1/users/auth/**").permitAll()
.requestMatchers("/api/v1/home/players/create").hasAuthority(SPECTATOR)
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
执行此操作时,通常不需要将会话标记为无状态,因为 HTTP Basic 的身份验证过滤器首先不会访问会话。
然后,在 Postman 中测试时,使用 HTTP Basic 和用户名/密码凭据设置
Authorization
标头。
最后,考虑自定义
UserDetailsService
,而不是自定义身份验证提供程序;如果您分享您的 AuthenticationProvider
实现,我会很乐意在那里更新我的答案并提供更有针对性的指导。