package org.keycloak.adapters.springsecurity.config;

import org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler;
import org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter;
import org.keycloak.adapters.springsecurity.filter.KeycloakCsrfRequestMatcher;
import org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter;
import org.keycloak.adapters.springsecurity.management.HttpSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;

/**
 * Provides a convenient base class for creating a {@link WebSecurityConfigurer}
 * instance secured by Keycloak. This implementation allows customization by overriding methods.
 *
 * @author <a href="mailto:srossillo@smartling.com">Scott Rossillo</a>
 * @version $Revision: 1 $
 *
 * @see EnableWebSecurity
 * @see EnableWebMvcSecurity
 */
public abstract class KeycloakWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter implements WebSecurityConfigurer<WebSecurity> {

    @Bean
    protected AdapterDeploymentContextBean adapterDeploymentContextBean() {
        return new AdapterDeploymentContextBean();
    }

    @Bean
    protected AuthenticationEntryPoint authenticationEntryPoint()
    {
        return new KeycloakAuthenticationEntryPoint();
    }

    @Bean
    protected KeycloakAuthenticationProvider keycloakAuthenticationProvider() {
        return new KeycloakAuthenticationProvider();
    }

    @Bean
    protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception {
        KeycloakAuthenticationProcessingFilter filter  = new KeycloakAuthenticationProcessingFilter(authenticationManagerBean());
        filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy());
        return filter;
    }

    @Bean
    protected KeycloakPreAuthActionsFilter keycloakPreAuthActionsFilter() {
        return new KeycloakPreAuthActionsFilter(httpSessionManager());
    }

    protected KeycloakCsrfRequestMatcher keycloakCsrfRequestMatcher() {
        return new KeycloakCsrfRequestMatcher();
    }

    @Bean
    protected HttpSessionManager httpSessionManager() {
        return  new HttpSessionManager();
    }

    @Bean
    protected KeycloakLogoutHandler keycloakLogoutHandler() {
        return new KeycloakLogoutHandler(adapterDeploymentContextBean());
    }

    protected abstract SessionAuthenticationStrategy sessionAuthenticationStrategy();

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement()
                .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
                .and()
                .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
                .addFilterBefore(keycloakAuthenticationProcessingFilter(), X509AuthenticationFilter.class)
                .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint());
    }
}

@@ -1503,25 +1503,23 @@
 ion.
-preauth.x509.X509
+session.Session
 Auth
@@ -1528,22 +1528,24 @@
 tication
-Filter
+Strategy
 ;%0Aimport
@@ -1589,39 +1589,33 @@
 hentication.
-session.Session
+www.Basic
 Authenticati
@@ -1616,24 +1616,22 @@
 tication
-Strategy
+Filter
 ;%0A%0A/**%0A 
@@ -2255,34 +2255,24 @@
 n();%0A    %7D%0A%0A
-    @Bean%0A
     protecte
@@ -2389,34 +2389,24 @@
 t();%0A    %7D%0A%0A
-    @Bean%0A
     protecte
@@ -3301,34 +3301,24 @@
 r();%0A    %7D%0A%0A
-    @Bean%0A
     protecte
@@ -3608,32 +3608,33 @@
 ows Exception %7B%0A
+%0A
         http%0A   
@@ -3630,16 +3630,122 @@
    http%0A
+                .csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher())%0A                .and()%0A
         
@@ -4040,12 +4040,13 @@
 (), 
-X509
+Basic
 Auth
@@ -4158,16 +4158,217 @@
 Point())
+%0A                .and()%0A                .logout()%0A                .addLogoutHandler(keycloakLogoutHandler())%0A                .logoutUrl(%22/sso/logout%22).permitAll()%0A                .logoutSuccessUrl(%22/%22)
 ;%0A    %7D%0A

Improve Spring Security adapter default configuration