如果用户无法通过 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;
}
}