Spring Security+;KeyClope-如何处理Ajax请求与;“访问令牌寿命”;
我最近在Primefaces Spring Boot Web应用程序中实现了KeyClope。 除了一件事外,这一切都非常有效:在keydove的“访问令牌寿命”下设置任何内容后,Ajax请求“超时”。没有重定向。ajaxStatus永远不会结束,用户被迫重新加载页面。看看这个请求,我得到了401“未经授权” 例如,用户加载一个站点并做他想做的任何事情。在没有重新加载或导航到另一个页面的情况下5分钟后,ajax请求会被未经授权 所以我的问题是:在这种情况下,什么是最佳实践?这是预期的行为吗 我看到以下选择:Spring Security+;KeyClope-如何处理Ajax请求与;“访问令牌寿命”;,ajax,spring,spring-security,primefaces,keycloak,Ajax,Spring,Spring Security,Primefaces,Keycloak,我最近在Primefaces Spring Boot Web应用程序中实现了KeyClope。 除了一件事外,这一切都非常有效:在keydove的“访问令牌寿命”下设置任何内容后,Ajax请求“超时”。没有重定向。ajaxStatus永远不会结束,用户被迫重新加载页面。看看这个请求,我得到了401“未经授权” 例如,用户加载一个站点并做他想做的任何事情。在没有重新加载或导航到另一个页面的情况下5分钟后,ajax请求会被未经授权 所以我的问题是:在这种情况下,什么是最佳实践?这是预期的行为吗 我看
@Configuration
@KeycloakConfiguration
@EnableWebSecurity
@EnableGlobalMethodSecurity(proxyTargetClass = true)
public class SpringSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
private KeycloakClientRequestFactory keycloakClientRequestFactory;
@Inject
public void setKeycloakClientRequestFactory(KeycloakClientRequestFactory keycloakClientRequestFactory) {
this.keycloakClientRequestFactory = keycloakClientRequestFactory;
}
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
grantedAuthorityMapper.setPrefix("ROLE_");
grantedAuthorityMapper.setConvertToUpperCase(true);
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
public KeycloakConfigResolver KeycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(
new SessionRegistryImpl());
}
@Bean
public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
KeycloakAuthenticationProcessingFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(true);
return registrationBean;
}
@Bean
public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
KeycloakPreAuthActionsFilter filter) {
FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
registrationBean.setEnabled(true);
return registrationBean;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/javax.faces.resource/**").permitAll()
.antMatchers("/pages/accessdenied*").permitAll()
.antMatchers("/pages/admin/**").hasRole("ADMIN")
.antMatchers("/pages/shared/**").permitAll()
.antMatchers("/pages/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.csrf().disable();
}
}
钥匙斗篷设置
由于Spring安全适配器使用web会话,我建议您执行两个步骤(您至少需要实现第二个步骤): 1。增加领域的KC会话超时: 这说明会话将持续多长时间进行访问(考虑刷新令牌的使用寿命)。此值与您希望允许用户进入而无需再次验证自己的程度有关 不建议增加访问令牌的使用寿命,因为能够截获一个令牌的攻击者将有更宽的时间窗口来执行有效操作 2。在视图端,控制401个异常 即使您有一个长期的会话,401个异常仍然可能发生。因此,您需要在视图侧控制它们。例如,使用AngularJs,在发生401代码的情况下,将用户重定向到登录页面的一种非常基本的方法可能是这样的(放入一些拦截器):
对于Primefaces,您最好在服务器筛选器中实现一些逻辑,如果您的业务逻辑发送401响应,它将重定向到
/SSO/logout
。增加SSO会话空闲时间无助于解决我当前的问题。它已经设置为30分钟,这正是我所需要的。在401s上重定向是拦截ajax请求的一个很好的提示。访问令牌寿命是否有一个“最大”值,该值应用于不太容易受到攻击?5分钟对于我的应用程序来说太短了,因为我在一个站点上有很多统计数据,这些数据是按需加载的(触发ajax请求)…访问令牌更新过程应该由Spring安全适配器自动处理(理论上,如果配置正确,在任何情况下都不应该得到401)。因此,适配器应能在1分钟或5分钟内正常工作。一般来说,建议访问令牌的寿命较短。尽管如此,如果您使用HTTPS进行连接,应该没有人能够检索您的令牌。@XtremeBiker我有一个类似的问题。。但我不需要登录,只要刷新pag(F5),我就可以安全地使用我的应用程序。。为什么?
keycloak.enabled=true
keycloak.auth-server-url=http://host:8090/auth
keycloak.realm="realm"
keycloak.public-client=true
keycloak.resource="client-name"
keycloak.principal-attribute=preferred_username
function responseError(response) {
console.log('error: ' + JSON.stringify(response));
if (!(response.status === 401)) {
$rootScope.$emit('httpError', response);
} else {
//401 error
window.location.href = window.location.protocol + '//'
+ window.location.host + '/sso/logout';
}
return $q.reject(response);
}