当前位置: 首页 > 知识库问答 >
问题:

Spring Security Key斗篷——如何结合“访问令牌寿命”处理Ajax请求

盛建德
2023-03-14

我最近在Primefaces Spring Boot Web应用程序中实现了KeyClope。除了一件事之外,这一切都非常有效:在KeyClope中“访问令牌寿命”下设置的任何内容之后,Ajax请求“超时”。没有重定向。ajaxStatus永远不会结束,用户被迫重新加载页面。看看这个请求,我得到了401“未经授权”。

例如,用户加载一个站点并做他想做的任何事情。在没有重新加载或导航到另一个页面的情况下,5分钟后,ajax请求会被授权。

所以我的问题是:在这种情况下,什么是最佳实践,这是预期的行为吗?

我看到以下选项:

  1. 增加“访问令牌寿命”
  2. 如果用户不再被授权,拦截ajax调用并重新加载页面-

这是我的SpringSecurity和Keycloak配置:

@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();
    }


}
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

共有1个答案

董鸣
2023-03-14

由于Spring Security适配器使用web会话,我建议您执行两个步骤(您至少需要实现第二个步骤):

1.增加领域的KC会话超时:

这告诉会话对访问的持续时间(负责刷新令牌寿命)。此值与您希望让用户进入而无需再次验证自己的程度有关。

不建议延长访问令牌的使用寿命,因为能够拦截一个令牌的攻击者将有更大的时间窗口来执行有效的操作。

2.在您的视图端,控制401个异常

即使你有一个长期的会议,401例外仍然可能发生。所以你需要在视图中控制它们。例如,使用AngularJs,如果发生401代码,将用户重定向到登录页面的一种非常基本的方法可能是这样的(放入一些拦截器):

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);
}

对于Primefaces,最好是在服务器过滤器中实现一些逻辑,如果业务逻辑发送401响应,它将重定向到/SSO/logout

 类似资料:
  • 使用KeyCloak时,访问令牌与用户信息令牌有何不同? 从OAuth2/OpenIDConnect中,我了解到访问令牌提供了用户已经通过身份验证的信息,您需要使用用户信息令牌来获取关于用户及其配置文件/角色等的更多信息。 当我看到访问令牌时https://jwt.io/而不是用户信息令牌。我能够获得与用户配置文件相同的信息 为什么会这样,使用Keycloak时访问令牌与用户信息令牌有何不同?

  • 我已经做了大约一个星期了。 我有一个用例,我通过主体而不是标题接收身份验证令牌,并且由于keybeapt和Spring不会自动设置用户。(原因是,对于WebSocket,我只能通过具有初始连接的主体发送身份验证令牌) 我尝试在keycloak之前拦截调用并将令牌从正文复制到标头,但这不起作用。 所以现在我想通过keydepeat手动进行身份验证(或者只是手动设置主要用户)。我可以访问JWT访问令牌

  • 我想获取JWT Access令牌用于Docuse,我尝试使用以下代码获取访问令牌,之后我通过访问令牌创建信封,我得到一个错误 “调用创建信封时出错: { ”错误代码“: ”AUTHORIZATION_INVALID_TOKEN“,”消息“:”提供的访问令牌已过期、已吊销或格式不正确。 我从这个链接DocuSign JWT访问令牌请求以上代码,在用户提到的工作代码,请告诉我我犯了什么错误,注意:我正

  • 谁知道如何使用获取id_令牌? 我一直在(Spring,JEE)和postman中与合作。 基本的工作正常,但我需要,因为有一些声明,它们不存在于中,但它们存在于中。 使用库,我可以获得Keycloak上下文,但id_token属性始终为null。 有什么主意吗?

  • 客户端通过使用按附录B“application/x-www-form-urlencoded”格式在HTTP请求实体正文中发送下列UTF-8字符编码的参数向令牌端点发起请求: grant_type 必需的。值必须设置为“client_credentials”。 scope 可选的。如3.3节所述的访问请求的范围。 客户端必须如3.2.1所述与授权服务器进行身份验证。 例如,客户端使用传输层安全发起如

  • 客户端通过使用按附录B“application/x-www-form-urlencoded”格式在HTTP请求实体正文中发送下列UTF-8字符编码的参数向令牌端点发起请求: grant_type 必需的。值必须设置为“password”。 username 必需的。资源所有者的用户名。 password 必需的。资源所有者的密码。 scope 可选的。如3.3节所述的访问请求的范围。 如果客户端类