1

如果用户无法通过 Kerberos 登录,则重定向到普通授权页面(通过登录名和密码表单)时会出现问题。在类的doFilter()方法中KerberosAuthFilter,如果标头结果为空或不满足要求(下面的代码),我会执行重定向,但不是从somehost:9090/tosomehost:9090/login页面重定向,而是无限输出字符串“redirect” .

请帮我解决这个问题。下面的代码

PS 通过 Kerberos 授权也可以通过登录名和密码表单进行授权,唯一的问题是我无法配置重定向到/login

// part of SecurityConfig
@Override
    protected void configure(HttpSecurity http) throws Exception {

        http.headers()
                .frameOptions()
                .sameOrigin()
                .and()
                .csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint(spnegoEntryPoint())
                .and()
                .authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/api/file/*").permitAll()
                .antMatchers("/api/company/*/portals").permitAll()
                .antMatchers("/api/portal/logo/**").permitAll()
                .antMatchers("/api/**", "/ticket/otId/*").authenticated()
                .antMatchers("/admin**").hasAnyRole("ADMIN", "ARTICLE_EDITOR", "NEWS_EDITOR", "CATALOG_EDITOR", "CATALOG_OBSERVER")
                .antMatchers("/support**").hasRole("SUPPORT")
                .antMatchers("/redirect**").authenticated()

                .and()
                .formLogin()
                .permitAll()
                .loginProcessingUrl(LOGIN_URL)
                .usernameParameter(LOGIN_PARAM)
                .passwordParameter(PASSWORD_PARAM)
                .successHandler(authenticationSuccessHandler)
                .failureHandler(portalAuthenticationFailureHandler)
                .and()
                .logout()
                .logoutUrl(LOGOUT_URL)
                .logoutSuccessUrl(LOGIN_PAGE_URL)
                .and()
                .rememberMe()
                .rememberMeParameter(REMEMBER_ME_PARAM)
                .rememberMeCookieName(REMEMBER_ME_COOKIE_NAME)
                .tokenRepository(tokenRepository)
                .tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(1))
                .and()
                .addFilterBefore(kerberosAuthFilter(),
                        BasicAuthenticationFilter.class);
    }

    @Bean
    public SpnegoEntryPoint spnegoEntryPoint() {
        return new SpnegoEntryPoint();
    }

    @Bean
    public KerberosAuthFilter kerberosAuthFilter() {
        KerberosAuthFilter filter = new KerberosAuthFilter();

        try {
            filter.setAuthenticationManager(authenticationManagerBean());
            filter.setFailureHandler(kerberosAuthenticationFailureHandler);
        } catch (Exception e) {
            log.error("FAILED TO SET AuthenticationManager on SpnegoAuthenticationProcessingFilter\n", e);
        }

        return filter;
    }

// doFilter() in KerberosAuthFilter
//the KerberosAuthFilter class is the same as the custom SpnegoAuthenticationProcessingFilter, //except for the end of the doFilter () method
  @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        if (skipIfAlreadyAuthenticated) {
            Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();

            if (existingAuth != null && existingAuth.isAuthenticated()
                    && (existingAuth instanceof AnonymousAuthenticationToken) == false) {
                chain.doFilter(request, response);
                return;
            }
        }

        String header = request.getHeader("Authorization");

        if (header != null && (header.startsWith("Negotiate ") || header.startsWith("Kerberos "))) {
            if (logger.isDebugEnabled()) {
                logger.debug("Received Negotiate Header for request " + request.getRequestURL() + ": " + header);
            }
            byte[] base64Token = header.substring(header.indexOf(" ") + 1).getBytes("UTF-8");
            byte[] kerberosTicket = Base64.decode(base64Token);
            KerberosServiceRequestToken authenticationRequest = new KerberosServiceRequestToken(kerberosTicket);
            authenticationRequest.setDetails(authenticationDetailsSource.buildDetails(request));
            Authentication authentication;
            try {
                authentication = authenticationManager.authenticate(authenticationRequest);
            } catch (AuthenticationException e) {
                logger.warn("Negotiate Header was invalid: " + header, e);
                SecurityContextHolder.clearContext();
                if (failureHandler != null) {
                    failureHandler.onAuthenticationFailure(request, response, e);
                } else {
                    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    response.flushBuffer();
                }
                return;
            }
            sessionStrategy.onAuthentication(authentication, request, response);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            if (successHandler != null) {
                successHandler.onAuthenticationSuccess(request, response, authentication);
            }
            chain.doFilter(request, response);
        } else {
            response.sendRedirect("/login.html");
            System.out.println("redirect");
            return;
        }

    }

日志:在此处输入图像描述

在重定向后的浏览器结果中: 在此处输入图像描述

4

0 回答 0