Search code examples
spring-securityspring-bootnetflix-zuul

How to revert to /login on zuul proxied url if not authenticated


I have a 2 spring boot applications running with one application serving as a "Gateway" to manage authentication and routing (with zuul proxy) and the other as a UI("/admin") behind the gateway.

When I hit "/login"(or any other endpoint on the gateway itself) I get routed to the "login.html" page, then I can enter my credentials and get authenticated correctly. After which I can access the "/admin" with no problem.

My problem is, if I hit "/admin" before being authenticated, I don't get routed to "/login.html" but only get the "basic auth" popup asking for credential, which is what I don't want.

Here is my config on the gateway server.

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .sessionManagement()
            .maximumSessions(1)
                .expiredUrl("/login")
                    .maxSessionsPreventsLogin(false)
                        .sessionRegistry(sessionRegistry())
        .and()
            .sessionCreationPolicy( SessionCreationPolicy.ALWAYS)
                .invalidSessionUrl( "/login" );
        http.addFilterBefore(new ApiKeyAuthenticationFilter(macSigner()), BasicAuthenticationFilter.class);
        http.httpBasic().and()
        .authorizeRequests()
            .antMatchers("/", "/home", "/index","/support.html", "/about.html","/features.html","/fonts/**","/ws/**",
                    "/contacts.html","/img/**","/logos/**","/docs/**").permitAll()
            .antMatchers("/admin**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
                .csrf().ignoringAntMatchers("/resource/api/**","/api/**").csrfTokenRepository(csrfTokenRepository())
            .and()
        .addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class)
        .logout()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login")
            .permitAll();
    }

and here is the config on my Admin server

@Override
        protected void configure(HttpSecurity http) throws Exception {
            http.httpBasic().and().authorizeRequests().anyRequest().authenticated();
            http.csrf().disable();
        }

Can anyone give me some advice as to where to dig please?


Solution

  • Try using authenticationEntryPoint as well as the LoginUrlAuthenticationEntryPoint.

    for example

     @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                    .httpBasic().and().exceptionHandling()
                    .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")).and()
                    .logout().and()
                    .authorizeRequests()
                    .antMatchers("/index.html", "/login", "/").permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .csrf()
                    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
            // @formatter:on
        }
    
        @RequestMapping("/login")
        public String login() {
            return "forward:/";
        }