401 SPNEGO SSO 与 Linux 客户端
401 SPNEGO SSO with Linux client
我无法将我的 Ubuntu 虚拟机配置为在 Spnego 下的 Spring 安全 Web 应用程序上进行单点登录。我是不是做错了什么,还是遗漏了什么?
我已经在 Windows 7 VM 上进行 SSO,所以我相信它是 Linux 特定的。
下面是我的详细配置。
基础设施
我有四台机器 运行 在两种不同的硬件中:
WIN-SRV2008.company.local
: VM KDC 运行ning Windows Server 2008 (硬件 A)
TOMCAT.company.local
:运行安装 Tomcat 7
网络应用程序(硬件 A)
W7-CLIENT.company.local
:VM Windows 7 个客户端,SSO 工作(硬件 B)
U-CLIENT.company.local
:VM Ubuntu 17.10.1 客户端 SSO 不工作(硬件 B )
SPN
我的 SPN、krb5.ini
和 login.conf
基于 。
Spnego
我基本上遵循 Spring Security Kerberos - Reference Documentation,除了删除表单登录,导致:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${kerberos.service-principal}")
private String servicePrincipal;
@Value("${kerberos.keytab-location}")
private String keytabLocation;
@Override
protected void configure(HttpSecurity http) throws Exception {
AffirmativeBased affirmativeBased = new AffirmativeBased(Arrays.asList(new RoleVoter(),new WebExpressionVoter()));
http
.authorizeRequests().accessDecisionManager(affirmativeBased)
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(entryPoint())
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.and()
.addFilterBefore(
spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
BasicAuthenticationFilter.class)
.sessionManagement()
.invalidSessionUrl("/login")
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(kerberosAuthenticationProvider())
.authenticationProvider(kerberosServiceAuthenticationProvider());
}
@Bean
public SpnegoEntryPoint entryPoint() {
return new SpnegoEntryPoint();
}
@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
LoginKerberosAuthentication provider = new LoginKerberosAuthentication();
SunJaasKerberosClient client = new SunJaasKerberosClient();
client.setDebug(true);
provider.setKerberosClient(client);
provider.setUserDetailsService(usuarioDetailsService());
return provider;
}
@Bean
public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
AuthenticationManager authenticationManager) {
SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
filter.setAuthenticationManager(authenticationManager);
return filter;
}
@Bean
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(sunJaasKerberosTicketValidator());
provider.setUserDetailsService(usuarioDetailsService());
return provider;
}
@Bean
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
ticketValidator.setServicePrincipal(servicePrincipal);
ticketValidator.setKeyTabLocation(new FileSystemResource(keytabLocation));
ticketValidator.setDebug(true);
return ticketValidator;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public UsuarioDetailsService usuarioDetailsService() {
return new UsuarioDetailsService();
}
Ubuntu 客户
要加入域,我遵循了以下步骤:
sudo apt-get install realmd krb5-user software-properties-common python-software-properties packagekit
sudo realm join COMPANY.local -U 'administrator@COMPANY.LOCAL' -v
直到我生成 kerberos 票据:
kinit my_ubuntu_user@COMPANY.local
我实际上用 klist
检查缓存,输出:
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: my_ubuntu_user@COMPANY.local
Valid starting Expires Service principal
30/10/2018 17:25:47 31/10/2018 03:25:47 krbtgt/COMPANY.local@COMPANY.local
renew until 31/10/2018 17:25:43
最后,我使用以下方法成功验证:
sudo su my_ubuntu_user@COMPANY.local
SSO - 问题
当我尝试使用 Firefox(具有可信站点配置)访问我的应用程序主页时,就像我使用 Windows 7 客户端一样,我只得到 the 401 Negotiate header 并且没有发送响应令牌。
这意味着,当我将实际的 url 输入到 SpnegoEntryPoint
构造函数时,我会被重定向到此回退。
提前致谢
多亏了 Samson 的评论,我才能够让它发挥作用。
我确实通过 sudo su my_ubuntu_user@COMPANY.local
切换到空缓存,是什么让我的应用程序登录响应 401。
我无法将我的 Ubuntu 虚拟机配置为在 Spnego 下的 Spring 安全 Web 应用程序上进行单点登录。我是不是做错了什么,还是遗漏了什么?
我已经在 Windows 7 VM 上进行 SSO,所以我相信它是 Linux 特定的。
下面是我的详细配置。
基础设施
我有四台机器 运行 在两种不同的硬件中:
WIN-SRV2008.company.local
: VM KDC 运行ning Windows Server 2008 (硬件 A)TOMCAT.company.local
:运行安装Tomcat 7
网络应用程序(硬件 A)W7-CLIENT.company.local
:VM Windows 7 个客户端,SSO 工作(硬件 B)U-CLIENT.company.local
:VM Ubuntu 17.10.1 客户端 SSO 不工作(硬件 B )
SPN
我的 SPN、krb5.ini
和 login.conf
基于
Spnego
我基本上遵循 Spring Security Kerberos - Reference Documentation,除了删除表单登录,导致:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${kerberos.service-principal}")
private String servicePrincipal;
@Value("${kerberos.keytab-location}")
private String keytabLocation;
@Override
protected void configure(HttpSecurity http) throws Exception {
AffirmativeBased affirmativeBased = new AffirmativeBased(Arrays.asList(new RoleVoter(),new WebExpressionVoter()));
http
.authorizeRequests().accessDecisionManager(affirmativeBased)
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(entryPoint())
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.and()
.addFilterBefore(
spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
BasicAuthenticationFilter.class)
.sessionManagement()
.invalidSessionUrl("/login")
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(kerberosAuthenticationProvider())
.authenticationProvider(kerberosServiceAuthenticationProvider());
}
@Bean
public SpnegoEntryPoint entryPoint() {
return new SpnegoEntryPoint();
}
@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
LoginKerberosAuthentication provider = new LoginKerberosAuthentication();
SunJaasKerberosClient client = new SunJaasKerberosClient();
client.setDebug(true);
provider.setKerberosClient(client);
provider.setUserDetailsService(usuarioDetailsService());
return provider;
}
@Bean
public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
AuthenticationManager authenticationManager) {
SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
filter.setAuthenticationManager(authenticationManager);
return filter;
}
@Bean
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(sunJaasKerberosTicketValidator());
provider.setUserDetailsService(usuarioDetailsService());
return provider;
}
@Bean
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
ticketValidator.setServicePrincipal(servicePrincipal);
ticketValidator.setKeyTabLocation(new FileSystemResource(keytabLocation));
ticketValidator.setDebug(true);
return ticketValidator;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public UsuarioDetailsService usuarioDetailsService() {
return new UsuarioDetailsService();
}
Ubuntu 客户
要加入域,我遵循了以下步骤:
sudo apt-get install realmd krb5-user software-properties-common python-software-properties packagekit
sudo realm join COMPANY.local -U 'administrator@COMPANY.LOCAL' -v
直到我生成 kerberos 票据:
kinit my_ubuntu_user@COMPANY.local
我实际上用 klist
检查缓存,输出:
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: my_ubuntu_user@COMPANY.local
Valid starting Expires Service principal
30/10/2018 17:25:47 31/10/2018 03:25:47 krbtgt/COMPANY.local@COMPANY.local
renew until 31/10/2018 17:25:43
最后,我使用以下方法成功验证:
sudo su my_ubuntu_user@COMPANY.local
SSO - 问题
当我尝试使用 Firefox(具有可信站点配置)访问我的应用程序主页时,就像我使用 Windows 7 客户端一样,我只得到 the 401 Negotiate header 并且没有发送响应令牌。
这意味着,当我将实际的 url 输入到 SpnegoEntryPoint
构造函数时,我会被重定向到此回退。
提前致谢
多亏了 Samson 的评论,我才能够让它发挥作用。
我确实通过 sudo su my_ubuntu_user@COMPANY.local
切换到空缓存,是什么让我的应用程序登录响应 401。