keycloak-aplcache

Merge pull request #1233 from Smartling/KEYCLOAK-1274 Add

5/8/2015 2:10:03 AM

Details

diff --git a/docbook/reference/en/en-US/master.xml b/docbook/reference/en/en-US/master.xml
index 31dcd82..218a1aa 100755
--- a/docbook/reference/en/en-US/master.xml
+++ b/docbook/reference/en/en-US/master.xml
@@ -17,6 +17,7 @@
                 <!ENTITY Jetty8Adapter SYSTEM "modules/jetty8-adapter.xml">
                 <!ENTITY FuseAdapter SYSTEM "modules/fuse-adapter.xml">
                 <!ENTITY SpringBootAdapter SYSTEM "modules/spring-boot-adapter.xml">
+                <!ENTITY SpringSecurityAdapter SYSTEM "modules/spring-security-adapter.xml">
                 <!ENTITY InstalledApplications SYSTEM "modules/installed-applications.xml">
                 <!ENTITY Logout SYSTEM "modules/logout.xml">
                 <!ENTITY SAML SYSTEM "modules/saml.xml">
@@ -97,6 +98,7 @@ This one is short
         &FuseAdapter;
         &JavascriptAdapter;
         &SpringBootAdapter;
+        &SpringSecurityAdapter;
         &InstalledApplications;
         &Logout;
         &MultiTenancy;
diff --git a/docbook/reference/en/en-US/modules/spring-security-adapter.xml b/docbook/reference/en/en-US/modules/spring-security-adapter.xml
new file mode 100644
index 0000000..33c2aa2
--- /dev/null
+++ b/docbook/reference/en/en-US/modules/spring-security-adapter.xml
@@ -0,0 +1,275 @@
+<section id="spring-security-adapter">
+    <title>Spring Security Adapter</title>
+    <para>
+        To to secure an application with Spring Security and Keyloak, add this adapter as a dependency to your project.
+        You then have to provide some extra beans in your Spring Security configuration file and add the Keycloak security
+        filter to your pipeline.
+    </para>
+    <para>
+        Unlike the other Keycloak Adapters, you should not configure your security in web.xml. However, keycloak.json is still required.
+    </para>
+    <section>
+        <title>Adapter Installation</title>
+        <para>
+            Add Keycloak Spring Security adapter as a dependency to your Maven POM or Gradle build.
+        </para>
+        <para>
+            <programlisting>
+                <![CDATA[
+<dependency>
+    <groupId>org.keycloak</groupId>
+    <artifactId>keycloak-spring-security-adapter</artifactId>
+    <version>&project.version;</version>
+</dependency>
+]]>
+            </programlisting>
+        </para>
+    </section>
+    <section>
+        <title>Spring Security Configuration</title>
+        <para>
+            The Keycloak Spring Security adapter takes advantage of Spring Security's flexible security configuration syntax.
+        </para>
+        <section>
+            <title>Java Configuration</title>
+            <para>
+                Keycloak provides a KeycloakWebSecurityConfigurerAdapter as a convenient base class for creating a
+                <ulink url="http://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/WebSecurityConfigurer.html">WebSecurityConfigurer</ulink>
+                instance. The implementation allows customization by overriding methods. While its use is not required, it greatly simplifies your security context configuration.
+            </para>
+            <para>
+                <programlisting>
+                    <![CDATA[
+@Configuration
+@EnableWebSecurity
+@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
+public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
+{
+    /**
+     * Registers the KeycloakAuthenticationProvider with the authentication manager.
+     */
+    @Autowired
+    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
+        auth.authenticationProvider(keycloakAuthenticationProvider());
+    }
+
+    /**
+     * Defines 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("/customers*").hasRole("USER")
+                .antMatchers("/admin*").hasRole("ADMIN")
+                .anyRequest().permitAll();
+    }
+}
+]]>
+                </programlisting>
+            </para>
+            <para>
+                You must provide a session authentication strategy bean which should be of type
+                <code>RegisterSessionAuthenticationStrategy</code> for public or confidential applications and
+                <code>NullAuthenticatedSessionStrategy</code> for bearer-only applications.
+            </para>
+            <para>
+                Spring Security's <code>SessionFixationProtectionStrategy</code> is currently not supported because it changes
+                the session identifier after login via Keycloak. If the session identifier changes, universal log out will not
+                work because Keycloak is unaware of the new session identifier.
+            </para>
+        </section>
+        <section>
+            <title>XML Configuration</title>
+            <para>
+                While Spring Security's XML namespace simplifies configuration, customizing the configuration can be a bit
+                verbose.
+            </para>
+            <para>
+                <programlisting>
+                    <![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:security="http://www.springframework.org/schema/security"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans
+       http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://www.springframework.org/schema/context
+       http://www.springframework.org/schema/context/spring-context.xsd
+       http://www.springframework.org/schema/security
+       http://www.springframework.org/schema/security/spring-security.xsd">
+
+    <context:component-scan base-package="org.keycloak.adapters.springsecurity" />
+
+    <security:authentication-manager alias="authenticationManager">
+        <security:authentication-provider ref="keycloakAuthenticationProvider" />
+    </security:authentication-manager>
+
+    <bean id="adapterDeploymentContextBean" class="org.keycloak.adapters.springsecurity.AdapterDeploymentContextBean" />
+    <bean id="keycloakAuthenticationEntryPoint" class="org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationEntryPoint" />
+    <bean id="keycloakAuthenticationProvider" class="org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider" />
+    <bean id="keycloakPreAuthActionsFilter" class="org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter" />
+    <bean id="keycloakAuthenticationProcessingFilter" class="org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter">
+        <constructor-arg name="authenticationManager" ref="authenticationManager" />
+    </bean>
+
+    <bean id="keycloakLogoutHandler" class="org.keycloak.adapters.springsecurity.authentication.KeycloakLogoutHandler">
+            <constructor-arg ref="adapterDeploymentContextBean" />
+    </bean>
+
+    <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
+        <constructor-arg name="logoutSuccessUrl" value="/" />
+        <constructor-arg name="handlers">
+            <list>
+                <ref bean="keycloakLogoutHandler" />
+                <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
+            </list>
+        </constructor-arg>
+        <property name="logoutRequestMatcher">
+            <bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
+                <constructor-arg name="pattern" value="/sso/logout**" />
+                <constructor-arg name="httpMethod" value="GET" />
+            </bean>
+        </property>
+    </bean>
+
+    <security:http auto-config="false" entry-point-ref="keycloakAuthenticationEntryPoint">
+        <security:custom-filter ref="keycloakPreAuthActionsFilter" before="LOGOUT_FILTER" />
+        <security:custom-filter ref="keycloakAuthenticationProcessingFilter" before="FORM_LOGIN_FILTER" />
+        <security:intercept-url pattern="/customers**" access="ROLE_USER" />
+        <security:intercept-url pattern="/admin**" access="ROLE_ADMIN" />
+        <security:custom-filter ref="logoutFilter" position="LOGOUT_FILTER" />
+    </security:http>
+
+</beans>
+]]>
+                </programlisting>
+            </para>
+        </section>
+    </section>
+    <section>
+        <title>Naming Security Roles</title>
+        <para>
+            Spring Security, when using role-based authentication, requires that role names start with <code>ROLE_</code>.
+            For example, an administrator role must be declared in Keycloak as <code>ROLE_ADMIN</code> or similar, not simply
+            <code>ADMIN</code>.
+        </para>
+    </section>
+    <section>
+        <title>Client to Client Support</title>
+        <para>
+            To simplify communication between clients, Keycloak provides an extension of Spring's <code>RestTemplate</code> that
+            handles bearer token authentication for you. To enable this feature your security configuration must add the
+            <code>KeycloakRestTemplate</code> bean. Note that it must be scoped as a prototype to function correctly.
+        </para>
+        <para>
+            For Java configuration:
+            <programlisting>
+                <![CDATA[
+@Configuration
+@EnableWebSecurity
+@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
+public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
+
+    ...
+
+    @Autowired
+    public KeycloakClientRequestFactory keycloakClientRequestFactory;
+
+    @Bean
+    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+    public KeycloakRestTemplate keycloakRestTemplate() {
+        return new KeycloakRestTemplate(keycloakClientRequestFactory);
+    }
+
+    ...
+}
+]]>
+            </programlisting>
+        </para>
+        <para>
+            For XML configuration:
+            <programlisting>
+                <![CDATA[
+<bean id="keycloakRestTemplate" class="org.keycloak.adapters.springsecurity.client.KeycloakRestTemplate" scope="prototype">
+    <constructor-arg name="factory" ref="keycloakClientRequestFactory" />
+</bean>
+]]>
+            </programlisting>
+        </para>
+        <para>
+            Your application code can then use <code>KeycloakRestTemplate</code> any time it needs to make a call to another
+            client. For example:
+            <programlisting>
+                <![CDATA[
+
+@Service
+public class RemoteProductService implements ProductService {
+
+    @Autowired
+    private KeycloakRestTemplate template;
+
+    private String endpoint;
+
+    @Override
+    public List<String> getProducts() {
+        ResponseEntity<String[]> response = template.getForEntity(endpoint, String[].class);
+        return Arrays.asList(response.getBody());
+    }
+}
+
+]]>
+            </programlisting>
+        </para>
+    </section>
+    <section>
+        <title>Spring Boot Configuration</title>
+        <para>
+            Spring Boot attempts to eagerly register filter beans with the web application context. Therefore,
+            when running the Keycloak Spring Security adapter in a Spring Boot environment, it may be necessary to add two
+            <code>FilterRegistrationBean</code>s to your security configuration to prevent the Keycloak filters from being
+            registered
+            twice.
+        </para>
+        <para>
+            <programlisting>
+                <![CDATA[
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter
+{
+    ...
+
+    @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;
+    }
+
+    ...
+}
+]]>
+            </programlisting>
+        </para>
+    </section>
+</section>