Mehrere WebSecurityConfigurerAdapters: JWT-Authentifizierung und Formularanmeldung in Spring Security

Lesezeit: 3 Minuten

Benutzer-Avatar
Mohammed H

Ich habe die Spring Boot App mit Thymeleaf. Ich verwende die Spring Security FormLogin-Methode für die Sicherheit und muss JWT jetzt nur für einige APIs hinzufügen.


@EnableWebSecurity
public class SecurityConfigurations {
    @Autowired
    UserDetailsServiceImpl userDetails;

    @Bean
    DaoAuthenticationProvider provider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(encoder());
        provider.setUserDetailsService(userDetails);
        return provider;
    }

    @Bean
    PasswordEncoder encoder() {
        return new BCryptPasswordEncoder();
    }

    @Configuration
    @Order(1)

    public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

        @Autowired
        private JwtRequestFilter jwtRequestFilter;

        @Autowired
        DaoAuthenticationProvider provider;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(provider);
        }

        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {

            httpSecurity.csrf().disable()

                    .authorizeRequests().antMatchers("/api/user/authenticate").permitAll()

                    .antMatchers("/api/user/**").hasRole("USER")
                    .and().
                    exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

            // Add a filter to validate the tokens with every request
            httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        }
    }

    @Configuration
    public static class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {
        @Autowired
        DaoAuthenticationProvider provider;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(provider);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/admin/admins**").hasAnyRole("SADMIN").antMatchers("/admin/**")
                    .hasAnyRole("ADMIN", "SADMIN", "WADMIN").antMatchers("/rest/**")
                    .hasAnyRole("ADMIN", "SADMIN", "WADMIN", "USER").antMatchers("/user/**").hasAnyRole("USER")
                    .anyRequest().permitAll().and().formLogin().loginPage("/sign-in-up")
                    .loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
                    .invalidateHttpSession(false).and().csrf().disable().cors();

        }
    }

}

Auf diese Weise funktioniert JWT gut, wie ich es brauche, aber das Formlogin wurde gestoppt und der Aufruf von “/signInProcess” gibt jetzt 404 aus:
signInProcess funktioniert nicht

HINWEIS: Wenn ich die Bestellung ändere und formLogin @order(1) mache, funktioniert es wieder, aber natürlich nicht.

Außerdem habe ich versucht, beide so zu kombinieren, jetzt funktioniert beides gut, aber das Problem mit der Ausnahmebehandlung, wenn der JWT-Authentifizierungsfehler die Formlogin-Thymeleaf-Fehlerseite zurückgibt:

@Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/admin/admins**").hasAnyRole("SADMIN").antMatchers("/admin/**")
                    .hasAnyRole("ADMIN", "SADMIN", "WADMIN").antMatchers("/rest/**")
                    .hasAnyRole("ADMIN", "SADMIN", "WADMIN", "USER").antMatchers("/user/**").hasAnyRole("USER")
                    .antMatchers("/api/user/authenticate").permitAll()
                    .antMatchers("/api/user/**").hasRole("USER")
                    .anyRequest().permitAll().and().formLogin().loginPage("/sign-in-up")
                    .loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
                    .invalidateHttpSession(false).and().csrf().disable().cors();
            
            http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

        }

irgendwelche Vorschläge, um diese Arbeit zu machen. Danke.

Benutzer-Avatar
Eleftheria Stein-Kousathana

Dein WebSecurityConfigurerAdapters verarbeitet die eingehenden Anfragen der Reihe nach.
Seit JWTSecurityConfig ist mit kommentiert @Order(1) Es wird die Anfragen zuerst bearbeiten.

Sie haben a nicht angegeben antMatcher für diesen Adapter, damit er allen Anforderungen entspricht.
Dies bedeutet, dass eine Anfrage niemals ankommt FormLoginConfigurationAdapterseit JWTSecurityConfig passt zu ihnen allen.

Falls Sie es wollen JWTSecurityConfig um sich nur auf bestimmte Anfragen zu beziehen, können Sie eine angeben antMatcher in Ihrer Sicherheitskonfiguration.
Unten ist ein Beispiel:

@EnableWebSecurity
public class SecurityConfigurations {

    @Configuration
    @Order(1)
    public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
           http
              .requestMatchers(matchers -> matchers
                  .antMatchers("/api/**") // apply JWTSecurityConfig to requests matching "/api/**"
              )
              .authorizeRequests(authz -> authz
                  .anyRequest().authenticated()
              )
              .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
        }
    }

    @Configuration
    public class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
           http
              .authorizeRequests(authz -> authz
                  .anyRequest().authenticated()
              )
              .formLogin();
        }
    }
}

Weitere Einzelheiten zu mehreren WebSecurityConfigurerAdapterdu kannst das … sehen mehrere HttpSecurity Abschnitt in den Spring Security-Referenzdokumenten.

Weitere Einzelheiten zum Unterschied zwischen authorizeRequests() und requestMatchers()du kannst sehen diese Stack Overflow-Frage.

1016050cookie-checkMehrere WebSecurityConfigurerAdapters: JWT-Authentifizierung und Formularanmeldung in Spring Security

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy