本文介绍了在呼叫“仅承载者"时出现问题.从springboot(客户端应用程序)到另一个spring boot(仅承载应用程序)的keycloak端点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我正在尝试从使用"KeycloakRestTemplate"的客户端应用程序访问仅承载端点.

Basically I'm trying to access a bearer-only endpoint from a client app which is using a "KeycloakRestTemplate".

我确实遵循1:1的准则(德语): https://blog.codecentric.de/2017/09/keycloak-und-spring-security-teil-1-einrichtung-frontend/

I did follow this guidelines 1:1 (it is in German) : https://blog.codecentric.de/2017/09/keycloak-und-spring-security-teil-1-einrichtung-frontend/

我的问题是,当我看到日志时,仅承载者一端的身份验证似乎成功,如下所示:

My problem is that when I see the logs, the authentication on the side of the bearer only endpoint seems successful, as shown bellow:

 Found [1] values in authorization header, selecting the first value for Bearer.
o.k.a.BearerTokenRequestAuthenticator    : Verifying access_token
o.k.a.BearerTokenRequestAuthenticator    :  access_token: [LONG TOKEN HERE]
o.k.a.RefreshableKeycloakSecurityContext : checking whether to refresh.
org.keycloak.adapters.AdapterUtils       : use realm role mappings
org.keycloak.adapters.AdapterUtils       : Setting roles:
org.keycloak.adapters.AdapterUtils       :    role: create_vouchers
org.keycloak.adapters.AdapterUtils       :    role: public_realm_access
org.keycloak.adapters.AdapterUtils       :    role: overview_orders
org.keycloak.adapters.AdapterUtils       :    role: uma_authorization
User 'c1500da2-855f-4306-ab65-662160558101' invoking 'http://localhost:8082/articles' on client 'articlesBearerOnlyService'
o.k.adapters.RequestAuthenticator        : Bearer AUTHENTICATED
.k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /articles
o.k.a.AuthenticatedActionsHandler        : AuthenticatedActionsValve.invoke http://localhost:8082/articles
cors validation not needed as were not a secure session or origin header was null: {0}
o.k.a.AuthenticatedActionsHandler        : Policy enforcement is disabled.

但随后在日志上直接出现以下内容:

but then directly afterwards on the logs comes this:

o.k.adapters.PreAuthActionsHandler       : adminRequest http://localhost:8082/login
o.k.adapters.PreAuthActionsHandler       : checkCorsPreflight http://localhost:8082/login
.k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /login
o.k.a.AuthenticatedActionsHandler        : AuthenticatedActionsValve.invoke http://localhost:8082/login
o.k.a.AuthenticatedActionsHandler        : Origin: null uri: http://localhost:8082/login
o.k.a.AuthenticatedActionsHandler        : cors validation not needed as were not a secure session or origin header was null: {0}
o.k.a.AuthenticatedActionsHandler        : Policy enforcement is disabled.

因此,它尝试重定向到adminRequest http://localhost:8082/login 吗?为什么,如何解决?

so, it tries to redirect to adminRequest http://localhost:8082/login? why, and how could this be solved?

我也曾尝试过邮递员(从令牌端点获取acces令牌)并将其粘贴到此仅承载者"端点的Authorization标头中,类似地,通过查看日志,用户似乎已被授权就像上面的第一个日志块一样,不同之处在于它不会尝试重定向到任何地方,但我会收到401.

I did also also tried with postman (getting the acces-token from the token end-point) and pasting it on the Authorization header of this "bearer-only" endpoint, and similarly by seeing the logs, the user seems authorized exacltly like in the first log block above, the diference is that is doesn't try to redirect anywhere but I receive a 401.

有人可以为可能的解决方案提供一些指导吗?

Could somebody please provide some guidance into a possible solution?

提前谢谢!

---------------------------------------- 编辑 ----------------------------------------

这是应用程序属性文件:

here is the application properties file:

server.port = 8082
spring.application.name = articleBearerOnlyService

keycloak.auth-server-url=http://localhost:8080/auth
keycloak.realm=[REALM]
keycloak.resource=articlesBearerOnlyService
keycloak.bearer-only=true
keycloak.cors=true
keycloak.credentials.secret=[SECRET]
keycloak.ssl-required = external

# access controlled through spring security
#keycloak.security-constraints[0].auth-roles[0]=overview_orders
#keycloak.security-constraints[0].security-collections[0].patterns[0]=/articles

logging.level.org.keycloak=TRACE

,这里是SecurityConfig:

and here the SecurityConfig :

@KeycloakConfiguration
@EnableWebSecurity
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    private final KeycloakClientRequestFactory keycloakClientRequestFactory;

    public SecurityConfig(KeycloakClientRequestFactory keycloakClientRequestFactory) {
        this.keycloakClientRequestFactory = keycloakClientRequestFactory;
        //to use principal and authentication together with @async
        SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
    }

    /* remove default spring "ROLE_" prefix appending to keycloak's roles*/
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        // NullAuthenticatedSessionStrategy() for bearer-only services
        return new NullAuthenticatedSessionStrategy();
    }

    /* configure cors & requests handling behaviour*/
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.cors()
                .and()
                .csrf()
                .disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
                .and()
                .authorizeRequests()
                .antMatchers("/articles").hasRole("overview_orders")
                .anyRequest().permitAll();
    }


    // Spring boot integration
    @Bean
    public KeycloakConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    // *************************** Avoid Bean redefinition ********************************
    @Bean
    public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
            KeycloakAuthenticationProcessingFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
            KeycloakPreAuthActionsFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(
            KeycloakAuthenticatedActionsFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakSecurityContextRequestFilterBean(
            KeycloakSecurityContextRequestFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    @Override
    @ConditionalOnMissingBean(HttpSessionManager.class)
    protected HttpSessionManager httpSessionManager() {
        return new HttpSessionManager();
    }
}

推荐答案

在这种特殊情况下,我的@KeycloakConfiguration类SecurityConfig {...}被完全忽略,因此该应用程序的行为就像在以下位置未提供安全配置一样全部.

In this particular case, my @KeycloakConfiguration class SecurityConfig{...}, was completely ignored, and thus the application behaved as if none security config was provided at all.

现在,为什么SecurityConfig被忽略?-原来是该课程的路径位置(我几乎感到羞耻);我通常将此类放在以下位置:

Now, why was the SecurityConfig ignored?- it turned out to be (I almost feel shame) path location of the class; I usually would place such a class under:

com.[company].[domain].configuration

就我而言(因为我仅使用keycloak + spring进行原型设计,而现在并不特别关注类的位置).我确实将SecurityConfig类放置在

In my case (since I'm only prototyping with keycloak + spring and not particularly concerned with class location right now). I did place my SecurityConfig class under:

com.[company].configuration

这使Spring Boot完全忽略了此类.

This made spring boot completely ignore this class.

后续问题:我是Sprint引导的新手,是否有100%的必要将所有代码放置在" com.[company]"下.[ domain].",而不修改pom(只是通过initializr创建了一个新创建的香草springboot项目)?

Follow up question: I'm new to Sprint boot, is it 100% necessary to place all code under "com.[company].[domain].configuration", without modifying the pom (just having a newly created vanilla springboot project via the initializr)?

这篇关于在呼叫“仅承载者"时出现问题.从springboot(客户端应用程序)到另一个spring boot(仅承载应用程序)的keycloak端点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 05:22