无需 JWT 的 Spring Security 身份验证

问题描述 投票:0回答:1

@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 错误。

java spring spring-boot spring-security
1个回答
0
投票

关于添加表单登录,您走在正确的轨道上,尽管考虑到您正在发布 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
实现,我会很乐意在那里更新我的答案并提供更有针对性的指导。

© www.soinside.com 2019 - 2024. All rights reserved.