0

I am dealing with this, since 7 hours ago ,and I cant find an explanation, for simplicity, I just did the example a little smaller. I need some URLs with security access (JWT), and other path (dashboard) with a form login.

This is my code:

@EnableWebSecurity
public class MultiHttpSecurityConfig {

@Autowired
private UserDetailsService jwtUserDetailsService;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .userDetailsService(jwtUserDetailsService)
        .passwordEncoder(passwordEncoder());
}

@Bean
public PasswordEncoder passwordEncoder() {
    return NoOpPasswordEncoder.getInstance();
}

@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    protected void configure(HttpSecurity http) throws Exception {

        http
            .csrf().disable()
                // Get Request and /Authenticate do not need authentication
            .authorizeRequests()
                .antMatchers("/authenticate", "/authenticate/**").permitAll()
                .antMatchers(HttpMethod.GET, "/api/**").permitAll()
                // all others do need authentication
                .anyRequest().authenticated()
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

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

@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

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

        http
            .authorizeRequests()
                .antMatchers("/dashboard/index.html").authenticated()
                .and()
            .formLogin();
    }
}

This example is working, the JWT mechanism works great. The only thing it does not work, is the form login. When I hit the browser localhost:8080/dashboard/index.html, the file appears.

This is what I need:

/authorize --> Anyone can hit that URL to get the JWT token

/api --> Get methods do not need authorization

/api --> All others verbs, do need a token.

/dashboard/index.html --> A form login should appear.

I know that anyRequest().authenticated(), it is in the first configuration but if I even comment that line, the second Order is totally ignored.

What should I add or remove to accomplish my idea?

dur
  • 15,689
  • 25
  • 79
  • 125
  • Hi ! I tried,but no luck. Even if i remove the Order ,i get :Caused by: java.lang.IllegalStateException: @Order on WebSecurityConfigurers must be unique. – Alexis Yair Jul 05 '21 at 12:37
  • Does this answer your question? [Multiple WebSecurityConfigurerAdapters: JWT authentication and form login in spring security](https://stackoverflow.com/questions/65654804/multiple-websecurityconfigureradapters-jwt-authentication-and-form-login-in-spr) – Eleftheria Stein-Kousathana Jul 06 '21 at 08:51
  • Hi ! Yes,i tried that before but 2 problems: 1-The given/solution code does not compile, I added and() after each authenticated() method 2-After doing that correction, in the browser when I hit /dashboard I see a login, that is ok . But when i try to reach my API using for example Postman and I hit localhost:8080/api/whatever ,the response is the html of the login page ! – Alexis Yair Jul 06 '21 at 13:57
  • Look ,i created a gist with the answer you gave in the post you mention. https://gist.github.com/alexisjk/ea1fa42b043ab885ad782e9fd024010d I can make it work the autenticate URL ,the /admin url (I see a form login), BUT anyone can hit /api and that url should be authenticated. – Alexis Yair Jul 06 '21 at 14:26
  • Did you try `@Ordered(Order.HighestPrecedence + 99)` ? – Amit Mishra Jul 07 '21 at 04:58
  • Amit Mishra ,i tried ,but no luck . I guess there is something wrong with my mapping . Could you check mi Gist file? – Alexis Yair Jul 08 '21 at 01:26

1 Answers1

1

In your FormLoginWebSecurityConfigurerAdapter, the antMatchers() should be called before authorizeRequests() - this indicate that this filter chain only apply request to /dashboard/index.html.

http.antMatcher("/dashboard/index.html")
    .authorizeRequests()
        .anyRequest().authenticated() // since this filter chain only apply to /dashboard/index.html, don't need use antMatchers() to check again
        .and()
    .formLogin();

For more info: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#multiple-httpsecurity

The second issue is that the Order of yourFormLoginWebSecurityConfigurerAdapter must be before (less than) ApiWebSecurityConfigurationAdapter. WebSecurityConfigurerAdapter has a default @Order of 100, so you should annotate @Order(0) on your FormLoginWebSecurityConfigurerAdapter.

Dickson
  • 1,201
  • 10
  • 19
  • Hi ! Thanks for your time. I tried that,but no luck. I had to change http.antMatchers for http.antMatcher ,because it does not compile. When i hit localhost:8080/dashboard/index.html,i get : Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Mon Jul 05 09:43:44 ART 2021 There was an unexpected error (type=Forbidden, status=403). It seems,the other filter (JWT) it s beeing applied again. – Alexis Yair Jul 05 '21 at 12:53
  • The funny thing now, it s if I remove ApiWebSecurityConfigurationAdapter ,I still get the same Whitelabel error than I told you above . This is a Puzzle! – Alexis Yair Jul 05 '21 at 13:00
  • The only way i have to make the form appears is doing this: http.authorizeRequests().antMatchers("/dashboard/index.html").authenticated().and().formLogin(); But now,the problem is that any request to the /api returns 403,even /authenticate that has a permitAll rule. Very strange – Alexis Yair Jul 05 '21 at 13:06
  • @AlexisYair `http.antMatcher` is correct, Dickson made a typo. But you also have to chnage the order as Dickson wrote. However, you have also another problem, see: https://stackoverflow.com/questions/39314176/filter-invoke-twice-when-register-as-spring-bean – dur Jul 07 '21 at 19:20
  • Yes I typo, I have updated the answer. But other than that, it should works. Can you show your debug log/exception stack trace of the 403 response? – Dickson Jul 08 '21 at 11:14