只有在redirect_uri localhost的情况下,使用nginx代理的key斗篷进行春季引导才有效



我一直在为这个而头疼。

我有一个使用Spring Boot在localhost:8082上运行的基本web应用程序,一个在localhost:8081上运行的dockerized密钥斗篷服务器和一个在端口80上运行的码头化nginx服务器。

当我在没有spring安全集成的情况下使用key斗篷时,访问安全资源的用户将被重定向到位于http://{key斗篷-server}/auth/rems/{myrealm}/protocol/openid-connect/auth/的key斗篷登录页面。。。一切都很顺利。

根据本教程和其他几篇教程,当我将spring-security添加到混合中时,我的应用程序突然尝试重定向到http://{myapp}/so/login,那里没有/so/login端点,所以我得到了404。

我只能通过在http://localhost:8082并将客户端的keycloft中的redirect_uri设置为http://localhost:8082/*。

我怀疑这可能与nginx配置有关,但在我将spring安全性添加到组合中之前,它一直在工作,所以我很头疼。这是我的nginx.conf

worker_processes 2;
events {
    worker_connections 1024;
}
http {
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Host   $host;
    proxy_set_header    X-Forwarded-Server $host;
    proxy_set_header    X-Forwarded-Port   $server_port;
    proxy_set_header    X-Forwarded-Proto  $scheme;
    # auth local (keycloak)
    server {
        listen  80;
        server_name auth.local;
            location / {
                # keycloak
                proxy_pass http://host.docker.internal:8081/;
            }
        }
        server {
            listen  80;
            server_name guardian.local;
                location / {
                    # send to portal
                    rewrite ^/(.*)$ http://guardian.local/portal/$1 permanent;
                }
                location /portal {
                    # guardian web-portal
                    proxy_pass http://host.docker.internal:8082;
                }
            }
}

我的安全配置类:

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
    // Submits the KeycloakAuthenticationProvider to the AuthenticationManager
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }
    /**
     * Used by Spring Security to add Keycloak config from spring config resource (like application.properties).
     * @return
     */
    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }
    // Specifies the session authentication strategy
    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
                .antMatchers("/portal/client*")
                .hasRole("user")
                .anyRequest()
                .permitAll();
    }
}

我的应用程序属性

server.port = 8082
keycloak.auth-server-url = http://auth.local/auth
keycloak.realm = myRealm
keycloak.resource = guardian-web-portal
keycloak.public-client = true
keycloak.use-resource-role-mappings = true
keycloak.principal-attribute = preferred_username

如有任何帮助,我们将不胜感激。我使用的是钥匙斗篷弹簧启动程序12.0.4和弹簧启动程序安全2.4.5。

尝试添加以下内容并将permitAll((更改为authenticated((

.antMatchers("/login*", "/error*", "/sso*" ).permitAll()

在上

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
    http.authorizeRequests()
            .antMatchers("/portal/client*")
            .hasRole("user")
            .anyRequest()
            .permitAll();
}

所以最终你会得到:

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
    http.authorizeRequests()
            .antMatchers("/login*", "/error*", "/sso*" ).permitAll()
            .antMatchers("/portal/client*")
            .hasRole("user")
            .anyRequest()
            .authenticated();
}

最新更新