简体   繁体   English

Spring Boot 2 Kerberos身份验证

[英]Spring boot 2 kerberos Authentication

I wanted to know how to use Spring Security Kerberos with Spring Boot 2.0. 我想知道如何在Spring Boot 2.0中使用Spring Security Kerberos。

We are currently trying to get the SPNego filter to work. 我们目前正在尝试使SPNego过滤器正常工作。

This is the error: 这是错误:

o.s.s.k.w.a.SpnegoAuthenticationProcessingFilter : Negotiate Header was invalid: Negotiate YHoGBisGAQUFAqBwMG6gMDAuBgorBgEEAYI3AgIKBgkqhkiC9xIBAgIGCSqGSIb3EgECAgYKKwYBBAGCNwICHqI6BDhOVExNU1NQAAEAAACXsgjiAwADADUAAAANAA0AKAAAAAYBsR0AAAAPSU5CT01WRDgxMTAzMURCRw==
org.springframework.security.authentication.BadCredentialsException: GSSContext name of the context initiator is null
    at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:173)
    at org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:153)
    at java.security.AccessController.doPrivileged(Native Method)

Currently we are trying to authenticate only a single endpoint ( /protected ), but we need to secure all the endpoints using kerberos authentication. 当前,我们正在尝试仅对单个端点( /protected )进行身份验证,但是我们需要使用kerberos身份验证来保护所有端点。 This is the web security config( same code is working with Spring Boot 1.5.13.RELEASE but not with Spring Boot 2.0.3.RELEASE ): 这是Web安全配置( 相同的代码适用于Spring Boot 1.5.13.RELEASE但不适用于Spring Boot 2.0.3.RELEASE ):

package com.findwise.kerberos.config;

import com.findwise.kerberos.localhost.LocalhostAuthFilter;
import com.findwise.kerberos.localhost.LocalhostAuthProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider;
import org.springframework.security.kerberos.authentication.sun.SunJaasKerberosTicketValidator;
import org.springframework.security.kerberos.client.config.SunJaasKrb5LoginConfig;
import org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter;
import org.springframework.security.kerberos.web.authentication.SpnegoEntryPoint;
import org.springframework.security.ldap.userdetails.LdapUserDetailsService;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import java.util.Collection;

/**
 * SpringSecurityConfig:
 * <p>
 * This is our main security configuration - It follows very closely the
 * examples provided by Spring.IO - Spring Security Kerberos.
 *
 * @author Peter Gylling - email: peter.jorgensen@findwise.com
 * @link http://docs.spring.io/spring-security-kerberos/docs/current/reference/htmlsingle/
 */
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${app.service-principal}")
    private String servicePrincipal;

    @Value("${app.keytab-location}")
    private String keytabLocation;

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

        httpSecurity
                .exceptionHandling()
                .authenticationEntryPoint(spnegoEntryPoint())
                .and().authorizeRequests().anyRequest().authenticated()
                .and().addFilterBefore( spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
                BasicAuthenticationFilter.class);
    }

    /**
     * This ensures a global configuration for the security of the application.
     *
     * @param auth
     * @param kerbServiceProvider
     */
    @Autowired
    protected void configureGlobal(AuthenticationManagerBuilder auth,
                                   LocalhostAuthProvider localhostAuthProvider,
                                   KerberosServiceAuthenticationProvider kerbServiceProvider) {
        auth
                .authenticationProvider(localhostAuthProvider)
                .authenticationProvider(kerbServiceProvider);
    }

    /**
     * Provide the default Spring Authentication Manager bean.
     * This is used by the SpnegoAuthenticationProcessingFilter as
     * part of the configuration.
     *
     * @return
     * @throws Exception
     * @see SpnegoAuthenticationProcessingFilter
     */
    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


    /**
     * LocalhostAuthProvider:
     * Provided with the username from the LocalAuthFilter the LocalhostAuthProvider
     * calls Ldap and extracts the roles of the current user.
     *
     * @return a configured localhost auth provider
     */
    @Bean
    public LocalhostAuthProvider localhostAuthProvider() {
        LocalhostAuthProvider localhostAuthProvider = new LocalhostAuthProvider();
        localhostAuthProvider.setUserDetailsService(new KerberosUserDetailsService());
        return localhostAuthProvider;
    }

    /**
     * LocalhostAuthFilter:
     * Graps the SPNEGO request before the Kerberos based SPNEGO authentication filter
     * and shortcuts the system to allow for local users. (The developer use cae).
     *
     * @param authenticationManager - Standard Spring Security
     * @return a configured LocalHostAuth filter.
     */
    @Bean
    public LocalhostAuthFilter localhostAuthFilter(AuthenticationManager authenticationManager) {
        LocalhostAuthFilter localhostAuthFilter = new LocalhostAuthFilter();
        localhostAuthFilter.setAuthenticationManager(authenticationManager);
        return localhostAuthFilter;
    }


    /**
     * Setup SpnegoEntryPoint to point to the login
     * page provided by the login.jsp page.
     *
     * @return
     */
    @Bean
    public SpnegoEntryPoint spnegoEntryPoint() {
        return new SpnegoEntryPoint("/protected");
    }

    /**
     * SpnegoAuthenticationProcessingFilter:
     * <p>
     * This is your friendly SSO filter, that kindly automatically
     * logs the user in if the Browser provides the actual credentials
     *
     * @param authenticationManager - with BeanIds.AUTHENTICATION_MANAGER
     * @return
     * @See AuthenticationManager
     */
    @Bean
    public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
            AuthenticationManager authenticationManager) {
        SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
        filter.setAuthenticationManager(authenticationManager);
        return filter;
    }

    /**
     * KerberosServiceAuthenticationProvider:
     * <p>
     * This bean is needed by the global AuthenticationManager bean as the only
     * accepted authentication providers.
     * <p>
     * To actually provide Spring Security with the required user details the
     * LdapUserDetailsService is provided to the service auth provider.
     * <p>
     * The Ldap service will not be used until the TicketValidator has granted
     * general access.
     *
     * @return - A configured Kerberos Service Auth Provider
     * @see SunJaasKerberosTicketValidator
     * @see LdapUserDetailsService
     */
    @Bean
    public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
        KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
        provider.setTicketValidator(sunJaasKerberosTicketValidator());
        provider.setUserDetailsService(new KerberosUserDetailsService());
        return provider;
    }

    /**
     * SunJaasKerberosTicketValidator
     * <p>
     * This bean will on behalf of the web application validate the visiting users provided
     * Kerberos Ticket. This will not kick in if the underlying JAAS and KRB5 configuration is
     * not working as expected.
     * <p>
     * Find the values of the servicePrincipal and keytabLocation in application.properties
     *
     * @return - A Kerberos Ticket Validator
     * @see KerberosGlobalConfig
     */
    @Bean
    public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
        SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
        ticketValidator.setServicePrincipal(servicePrincipal);
        ticketValidator.setKeyTabLocation(new FileSystemResource(keytabLocation));
        ticketValidator.setDebug(true);

        return ticketValidator;
    }


    /**
     * SunJaasKrb5LoginConfig
     * <p>
     * This is what you would previously find in a JAAS Conf file.
     * <p>
     * Find the servicePrincipal and keytabLocation is application.properties
     *
     * @return a configured JAAS login
     * @see SunJaasKrb5LoginConfig
     */
    @Bean
    public SunJaasKrb5LoginConfig loginConfig() {
        SunJaasKrb5LoginConfig loginConfig = new SunJaasKrb5LoginConfig();
        loginConfig.setKeyTabLocation(new FileSystemResource(keytabLocation));
        loginConfig.setServicePrincipal(servicePrincipal);
        loginConfig.setDebug(true);
        loginConfig.setIsInitiator(true);
        loginConfig.setUseTicketCache(true);
        return loginConfig;
    }


    protected static class KerberosUserDetailsService implements UserDetailsService {

        @Override
        public UserDetails loadUserByUsername(final String s) throws UsernameNotFoundException {
            return new UserDetails() {
                @Override
                public Collection<? extends GrantedAuthority> getAuthorities() {
                    return null;
                }

                @Override
                public String getPassword() {
                    return null;
                }

                @Override
                public String getUsername() {
                    return s;
                }

                @Override
                public boolean isAccountNonExpired() {
                    return true;
                }

                @Override
                public boolean isAccountNonLocked() {
                    return true;
                }

                @Override
                public boolean isCredentialsNonExpired() {
                    return true;
                }

                @Override
                public boolean isEnabled() {
                    return true;
                }
            };
        }
    }
}

Kerberos service principal didn't setup properly. Kerberos服务主体设置不正确。 Now its working fine. 现在它的工作正常。

Basic configuration steps : 基本配置步骤:

1) Krb5 conf should be loaded properly (it contains KDC and realm related information). 1)应该正确加载Krb5 conf(它包含KDC和领域相关信息)。

2) Service principal (HTTP/xyz) must be created and keytab should be provided as a configuration. 2)必须创建服务主体(HTTP / xyz),并应提供keytab作为配置。

3) If you are calling any rest service via client program then you need to provide user principal and keytab, or you can use local Kerberos cache (krb5_123x). 3)如果要通过客户端程序调用任何其他服务,则需要提供用户主体和密钥表,或者可以使用本地Kerberos缓存(krb5_123x)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM