Reference doc updates

This commit is contained in:
Janne Valkealahti
2015-03-10 17:40:08 +00:00
parent 7c3ff33235
commit 2bd3762921
19 changed files with 557 additions and 239 deletions

View File

@@ -207,6 +207,7 @@ configure(rootProject) {
doctype: 'book',
numbered: '',
'spring-version' : springVersion,
'spring-security-version' : springSecurityVersion,
revnumber : project.version
}

View File

@@ -3,6 +3,16 @@
:numbered!:
[appendix]
== Material Used in this Document
Dummy UserDetailsService used in samples because we don't have a real
user source.
[source,java,indent=0]
----
include::samples/DummyUserDetailsService.java[tags=snippetA]
----
[appendix]
== Crash Course to Kerberos
In any authentication process there are usually a three parties
@@ -21,7 +31,7 @@ one which really brings everything together and thus is the most
critical component in your environment. Because of this it is also
considered as a single point of failure.
Initially when `Kerberos` environment is setup and domain users
Initially when `Kerberos` environment is setup and domain user
principals created into to a database, encryption keys are also
created. These encryption keys are based on shared secrets(i.e. user
password) and actual passwords are never kept in a clear text.
@@ -32,7 +42,7 @@ Interestingly there is no communication between a `resource` and a
image:images/drawio-kerb-cc2.png[]
When client wants to authenticate itself with a resource it first
When client wants to authenticate itself with a `resource` it first
needs to communicate with a `KDC`. `Client` will craft a special package
which contains encrypted and unencrypted parts. Unencrypted part
contains i.e. information about a user and encrypted part other
@@ -40,7 +50,7 @@ information which is part of a protocol. `Client` will encrypt package
data with its own key.
When `KDC` receives this authentication package from a client it
checks who this client claims to be from an unencrypted part and based
checks who this `client` claims to be from an unencrypted part and based
on that information it uses `client` decryption key it already have in
its database. If this decryption is succesfull `KDC` knows that this
`client` is the one it claims to be.
@@ -66,8 +76,8 @@ received service ticket to a service which then thinks that I don't
know anything about this guy but he have me an authentication ticket.
What `service` can do next is try to decrypt that ticket and if that
operation is succesfull it knows that only other party who knows my
credentials is the `KDC` and because I trust him I can also trust this
client claiming to be who he is.
credentials is the `KDC` and because I trust him I can also trust that
this client is a one he claims to be.
[appendix]
== Setup Kerberos Environments
@@ -75,6 +85,7 @@ Doing a production setup of Kerberos environment is out of scope of
this document but this appendix provides some help to get you
started for setting up needed components for development.
[[setupmitkerberos]]
=== Setup MIT Kerberos
First action is to setup a new realm and a database.
@@ -144,7 +155,17 @@ policy
Enter password for principal "user1@EXAMPLE.ORG":
Re-enter password for principal "user1@EXAMPLE.ORG":
Principal "user1@EXAMPLE.ORG" created.
----
If you like you can create a keytab file for this user.
[source,text,indent=0]
----
kadmin: ktadd -k /tmp/user1.keytab user1@EXAMPLE.ORG
Entry for principal user1@EXAMPLE.ORG with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/user1.keytab.
Entry for principal user1@EXAMPLE.ORG with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/tmp/user1.keytab.
Entry for principal user1@EXAMPLE.ORG with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/tmp/user1.keytab.
Entry for principal user1@EXAMPLE.ORG with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/tmp/user1.keytab.
----
Lets create a service ticket for tomcat and export credentials to a
@@ -164,7 +185,7 @@ Entry for principal HTTP/neo.example.org@EXAMPLE.ORG with kvno 2, encryption typ
Entry for principal HTTP/neo.example.org@EXAMPLE.ORG with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/tmp/tomcat2.keytab.
----
[[setupwinkerberos]]
=== Setup Windows Domain Controller
This was tested using `Windows Server 2012 R2`
@@ -214,5 +235,88 @@ PS C:\> ktpass /out c:\tomcat.keytab /mapuser tomcat@EXAMPLE.ORG /princ HTTP/neo
This appendix provides generic information about troubleshooting
errors and problems.
[IMPORTANT]
====
If you think environment and configuration is correctly setup, do
double check and ask other person to check possible obvious mistakes
or typos. Kerberos setup is generally very brittle and it is not
always very easy to debug where the problem lies.
====
[source,text]
----
GSSException: Failure unspecified at GSS-API level (Mechanism level:
Invalid argument (400) - Cannot find key of appropriate type to
decrypt AP REP - RC4 with HMAC)
----
If you see abore error indicating missing key type, this will happen
with two different use cases. Firstly your JVM may not support
appropriate encryption type or it is disabled in your `krb5.conf`
file.
[source,text]
----
default_tkt_enctypes = rc4-hmac
default_tgs_enctypes = rc4-hmac
----
Second case is less obvious and hard to track because it will lead
into same error. This specific `GSSException` is throws also if you
simply don't have a required encryption key which then may be caused
by a misconfiguration in your kerberos server or a simply typo in your
principal.
[appendix]
[[browserspnegoconfig]]
== Configure Browsers for Spnego Negotiation
=== Firefox
Complete following steps to ensure that your Firefox browser is
enabled to perform Spnego authentication.
- Open Firefox.
- At address field, type *about:config*.
- In filter/search, type *negotiate*.
- Parameter *network.negotiate-auth.trusted-uris* may be set to
default *https://* which doesn't work for you. Replace this with
your server address.
=== Chrome
With Google Chrome you generally need to set command-line parameters
order to white list servers with Chrome will negotiate.
[source,text]
----
--auth-server-whitelist="*.example.com"
--auth-negotiate-delegate-whitelist="*.example.com"
----
You can see which policies are enable by typing *chrome://policy/*
into Chrome's address bar.
With Linux Chrome will also read policy files from
`/etc/opt/chrome/policies/managed` directory.
.mypolicy.json
[source,json]
----
{
"AuthServerWhitelist" : "*.example.org",
"AuthNegotiateDelegateWhitelist" : "*.example.org",
"DisableAuthNegotiateCnameLookup" : true,
"EnableAuthNegotiatePort" : true
}
----
=== Internet Explorer
Complete following steps to ensure that your Internet Explorer browser
is enabled to perform Spnego authentication.
- Open Internet Explorer.
- Click *Tools > Intenet Options > Security* tab.
- In *Local intranet* section make sure your server is trusted by i.e.
adding it into a list.

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -17,5 +17,5 @@ include::introduction.adoc[]
[[springandssk]]
include::ssk.adoc[]
include::samples.adoc[]
include::appendix.adoc[]

View File

@@ -6,5 +6,6 @@ application developers to Kerberos concepts with Spring.
== Requirements
Spring Security Kerberos {revnumber} is built and tested with JDK 7, Spring
Framework {spring-version}.
Spring Security Kerberos {revnumber} is built and tested with JDK 7,
Spring Security {spring-security-version} and Spring Framework {spring-version}.

View File

@@ -8,3 +8,8 @@ This reference documentations contains following parts.
<<springsecuritykerberos>> describes the usage of Spring Security
Kerberos
<<springsecuritykerberossamples>> describes the usage of Spring
Security Kerberos Samples
<<appendices>> generic support material

View File

@@ -0,0 +1,169 @@
[[springsecuritykerberossamples]]
= Spring Security Kerberos Samples
This part of the reference documentation is introducing samples
projects. Generally samples can be either compiled manually by
building main distribution from
https://github.com/spring-projects/spring-security-kerberos or using
nightly snapshots or actual release builds.
- http://repo.spring.io/libs-snapshot/org/springframework/security/kerberos/
- http://repo.spring.io/libs-release/org/springframework/security/kerberos/
[IMPORTANT]
====
If you download and run sample from a maven repo it will not work
until a correct configuration is applied. See notes below for specific
samples.
====
<<samples-sec-server-win-auth>> sample for Windows environment
<<samples-sec-server-client-auth>> sample using server side authenticator
<<samples-sec-server-spnego-form-auth>> sample using ticket validation
with spnego and form
<<samples-sec-server-spnego-form-auth-xml>> sample using ticket
validation with spnego and form (xml config)
[[samples-sec-server-win-auth]]
== Security Server Windows Auth Sample
Goals of this sample:
- In windows environment, User will be able to logon to application
with Windows Active directory Credential which has been entered
during log on to windows. There should not be any ask for
userid/password credentials.
- In non-windows environment, User will be presented with a screen
to provide Active directory credentials.
[source,yaml,indent=0]
----
server:
port: 8080
app:
ad-domain: EXAMPLE.ORG
ad-server: ldap://WIN-EKBO0EQ7TS7.example.org/
service-principal: HTTP/neo.example.org@EXAMPLE.ORG
keytab-location: /tmp/tomcat.keytab
----
In above you can see the default configuration for this sample. You
can override these settings using a normal Spring Boot tricks like
using command-line options or custom `application.yml` file.
Run a server.
[source,text,subs="attributes"]
----
$ java -jar sec-server-win-auth-{revnumber}.jar
----
[NOTE]
====
See <<setupwinkerberos>> for more instructions how to work with
windows kerberos environment.
====
Login to `Windows 8.1` using domain credentials and access sample
image:images/ie1.png[]
image:images/ie2.png[]
Access sample application from a non windows vm and use domain
credentials manually.
image:images/ff1.png[]
image:images/ff2.png[]
image:images/ff3.png[]
[[samples-sec-server-client-auth]]
== Security Server Side Auth Sample
This sample demonstrates how server is able to authenticate user
against kerberos environment using his credentials passed in via a
form login.
Run a server.
[source,text,subs="attributes"]
----
$ java -jar sec-server-client-auth-{revnumber}.jar
----
[source,yaml,indent=0]
----
server:
port: 8080
----
[[samples-sec-server-spnego-form-auth]]
== Security Server Spnego and Form Auth Sample
This sample demonstrates how a server can be configured to accept a
Spnego based negotiation from a browser while still being able to fall
back to a form based authentication.
Using a `user1` principal <<setupmitkerberos>>, do a kerberos login
either using credentials.
[source,text]
----
$ kinit user1
Password for user1@EXAMPLE.ORG:
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: user1@EXAMPLE.ORG
Valid starting Expires Service principal
10/03/15 17:18:45 11/03/15 03:18:45 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
renew until 11/03/15 17:18:40
----
or using a keytab file.
[source,text]
----
$ kinit -kt user1.keytab user1
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: user1@EXAMPLE.ORG
Valid starting Expires Service principal
10/03/15 17:25:03 11/03/15 03:25:03 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
renew until 11/03/15 17:25:03
----
Run a server.
[source,text,subs="attributes"]
----
$ java -jar sec-server-spnego-form-auth-{revnumber}.jar
----
Now you should be able to open your browser and let it do Spnego
authentication with existing ticket.
[NOTE]
====
See <<browserspnegoconfig>> for more instructions for configuring
browsers to use Spnego.
====
[source,yaml,indent=0]
----
server:
port: 8080
app:
service-principal: HTTP/neo.example.org@EXAMPLE.ORG
keytab-location: /tmp/tomcat.keytab
----
[[samples-sec-server-spnego-form-auth-xml]]
== Security Server Spnego and Form Auth Xml Sample
This is a same sample than <<samples-sec-server-spnego-form-auth>> but
using xml based configuration instead of JavaConfig.
Run a server.
[source,text,subs="attributes"]
----
$ java -jar sec-server-spnego-form-auth-xml-{revnumber}.jar
----

View File

@@ -9,9 +9,10 @@
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<sec:http>
<sec:intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_FULLY" />
<sec:form-login login-page="/login.html" default-target-url="/secure/index.jsp"/>
<sec:http use-expressions="true" >
<sec:intercept-url pattern="/" access="permitAll" />
<sec:intercept-url pattern="/home" access="permitAll" />
<sec:intercept-url pattern="/**" access="authenticated"/>
</sec:http>
<sec:authentication-manager alias="authenticationManager">

View File

@@ -4,60 +4,60 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<sec:http entry-point-ref="spnegoEntryPoint">
<sec:intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_FULLY" />
<sec:custom-filter ref="spnegoAuthenticationProcessingFilter"
position="BASIC_AUTH_FILTER" />
</sec:http>
<sec:http entry-point-ref="spnegoEntryPoint" use-expressions="true" >
<sec:intercept-url pattern="/" access="permitAll" />
<sec:intercept-url pattern="/home" access="permitAll" />
<sec:intercept-url pattern="/login" access="permitAll" />
<sec:intercept-url pattern="/**" access="authenticated"/>
<sec:form-login login-page="/login" />
<sec:custom-filter ref="spnegoAuthenticationProcessingFilter"
before="BASIC_AUTH_FILTER" />
</sec:http>
<bean id="spnegoEntryPoint"
class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="kerberosAuthenticationProvider" />
<sec:authentication-provider ref="kerberosServiceAuthenticationProvider" />
</sec:authentication-manager>
<bean id="spnegoAuthenticationProcessingFilter"
class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="kerberosAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
<property name="userDetailsService" ref="dummyUserDetailsService"/>
<property name="kerberosClient">
<bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
<property name="debug" value="true"/>
</bean>
</property>
</bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="kerberosServiceAuthenticationProvider" />
</sec:authentication-manager>
<bean id="spnegoEntryPoint"
class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" >
<constructor-arg value="/login" />
</bean>
<bean id="spnegoAuthenticationProcessingFilter"
class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="kerberosServiceAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
<property name="ticketValidator">
<bean
class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
<property name="servicePrincipal" value="${app.service-principal}" />
<property name="keyTabLocation" value="${app.keytab-location}" />
<property name="debug" value="true" />
</bean>
</property>
<property name="userDetailsService" ref="dummyUserDetailsService" />
</bean>
<bean id="kerberosServiceAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
<property name="ticketValidator">
<bean
class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
<property name="servicePrincipal" value="${krb.service.prinicipal}" />
<!-- Setting keyTabLocation to a classpath resource will most likely not work in a Java EE application Server -->
<!-- See the Javadoc for more information on that -->
<property name="keyTabLocation" value="${krb.keytab.location}" />
<property name="debug" value="${krb.debug}" />
</bean>
</property>
<property name="userDetailsService" ref="dummyUserDetailsService" />
</bean>
<!-- This bean definition enables a very detailed Kerberos logging -->
<bean
class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
<property name="debug" value="${krb.debug}" />
<property name="krbConfLocation" value="${krb.conf.location}"/>
</bean>
<!--
Just returns the User authenticated by Kerberos and gives him the
ROLE_USER
-->
<bean id="dummyUserDetailsService"
class="org.springframework.security.extensions.kerberos.sample.DummyUserDetailsService" />
<context:property-placeholder location="/WEB-INF/kerberos.properties"/>
class="org.springframework.security.extensions.kerberos.docs.DummyUserDetailsService" />
</beans>
<!-- end::snippetA[] -->

View File

@@ -1,3 +1,18 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.extensions.kerberos.docs;
import org.springframework.context.annotation.Bean;
@@ -6,11 +21,6 @@ import org.springframework.security.config.annotation.authentication.builders.Au
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider;
import org.springframework.security.extensions.kerberos.SunJaasKerberosClient;
@@ -19,49 +29,41 @@ import org.springframework.security.extensions.kerberos.SunJaasKerberosClient;
@EnableWebMvcSecurity
public class AuthProviderConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(kerberosAuthenticationProvider());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(kerberosAuthenticationProvider());
}
@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
SunJaasKerberosClient client = new SunJaasKerberosClient();
client.setDebug(true);
provider.setKerberosClient(client);
provider.setUserDetailsService(dummyUserDetailsService());
return provider;
}
@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
KerberosAuthenticationProvider provider =
new KerberosAuthenticationProvider();
SunJaasKerberosClient client = new SunJaasKerberosClient();
client.setDebug(true);
provider.setKerberosClient(client);
provider.setUserDetailsService(dummyUserDetailsService());
return provider;
}
@Bean
public DummyUserDetailsService dummyUserDetailsService() {
return new DummyUserDetailsService();
}
static class DummyUserDetailsService implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return new User(username, "notUsed", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_USER"));
}
}
@Bean
public DummyUserDetailsService dummyUserDetailsService() {
return new DummyUserDetailsService();
}
}
//end::snippetA[]

View File

@@ -9,9 +9,10 @@
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<sec:http>
<sec:intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_FULLY" />
<sec:form-login login-page="/login.html" default-target-url="/secure/index.jsp"/>
<sec:http use-expressions="true" >
<sec:intercept-url pattern="/" access="permitAll" />
<sec:intercept-url pattern="/home" access="permitAll" />
<sec:intercept-url pattern="/**" access="authenticated"/>
</sec:http>
<sec:authentication-manager alias="authenticationManager">

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.extensions.kerberos.docs;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
//tag::snippetA[]
public class DummyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
return new User(username, "notUsed", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_USER"));
}
}
//end::snippetA[]

View File

@@ -1,6 +1,20 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.extensions.kerberos.docs;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
@@ -9,11 +23,6 @@ import org.springframework.security.config.annotation.authentication.builders.Au
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider;
import org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider;
import org.springframework.security.extensions.kerberos.SunJaasKerberosClient;
@@ -27,93 +36,83 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFi
@EnableWebMvcSecurity
public class SpnegoConfig extends WebSecurityConfigurerAdapter {
@Value("${app.service-principal}")
private String servicePrincipal;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(spnegoEntryPoint())
.and()
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout()
.permitAll()
.and()
.addFilterBefore(
spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
BasicAuthenticationFilter.class);
}
@Value("${app.keytab-location}")
private String keytabLocation;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth
.authenticationProvider(kerberosAuthenticationProvider())
.authenticationProvider(kerberosServiceAuthenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(spnegoEntryPoint())
.and()
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.and()
.logout()
.permitAll()
.and()
.addFilterBefore(
spnegoAuthenticationProcessingFilter(authenticationManagerBean()),
BasicAuthenticationFilter.class);
}
@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
KerberosAuthenticationProvider provider =
new KerberosAuthenticationProvider();
SunJaasKerberosClient client = new SunJaasKerberosClient();
client.setDebug(true);
provider.setKerberosClient(client);
provider.setUserDetailsService(dummyUserDetailsService());
return provider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(kerberosAuthenticationProvider())
.authenticationProvider(kerberosServiceAuthenticationProvider());
}
@Bean
public SpnegoEntryPoint spnegoEntryPoint() {
return new SpnegoEntryPoint("/login");
}
@Bean
public KerberosAuthenticationProvider kerberosAuthenticationProvider() {
KerberosAuthenticationProvider provider = new KerberosAuthenticationProvider();
SunJaasKerberosClient client = new SunJaasKerberosClient();
client.setDebug(true);
provider.setKerberosClient(client);
provider.setUserDetailsService(dummyUserDetailsService());
return provider;
}
@Bean
public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
AuthenticationManager authenticationManager) {
SpnegoAuthenticationProcessingFilter filter =
new SpnegoAuthenticationProcessingFilter();
filter.setAuthenticationManager(authenticationManager);
return filter;
}
@Bean
public SpnegoEntryPoint spnegoEntryPoint() {
return new SpnegoEntryPoint("/login");
}
@Bean
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
KerberosServiceAuthenticationProvider provider =
new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(sunJaasKerberosTicketValidator());
provider.setUserDetailsService(dummyUserDetailsService());
return provider;
}
@Bean
public SpnegoAuthenticationProcessingFilter spnegoAuthenticationProcessingFilter(
AuthenticationManager authenticationManager) {
SpnegoAuthenticationProcessingFilter filter = new SpnegoAuthenticationProcessingFilter();
filter.setAuthenticationManager(authenticationManager);
return filter;
}
@Bean
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
SunJaasKerberosTicketValidator ticketValidator =
new SunJaasKerberosTicketValidator();
ticketValidator.setServicePrincipal("HTTP/servicehost.example.org@EXAMPLE.ORG");
ticketValidator.setKeyTabLocation(new FileSystemResource("/tmp/service.keytab"));
ticketValidator.setDebug(true);
return ticketValidator;
}
@Bean
public KerberosServiceAuthenticationProvider kerberosServiceAuthenticationProvider() {
KerberosServiceAuthenticationProvider provider = new KerberosServiceAuthenticationProvider();
provider.setTicketValidator(sunJaasKerberosTicketValidator());
provider.setUserDetailsService(dummyUserDetailsService());
return provider;
}
@Bean
public SunJaasKerberosTicketValidator sunJaasKerberosTicketValidator() {
SunJaasKerberosTicketValidator ticketValidator = new SunJaasKerberosTicketValidator();
ticketValidator.setServicePrincipal(servicePrincipal);
ticketValidator.setKeyTabLocation(new FileSystemResource(keytabLocation));
ticketValidator.setDebug(true);
return ticketValidator;
}
@Bean
public DummyUserDetailsService dummyUserDetailsService() {
return new DummyUserDetailsService();
}
static class DummyUserDetailsService implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return new User(username, "notUsed", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_USER"));
}
}
@Bean
public DummyUserDetailsService dummyUserDetailsService() {
return new DummyUserDetailsService();
}
}
//end::snippetA[]

View File

@@ -4,60 +4,60 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<sec:http entry-point-ref="spnegoEntryPoint">
<sec:intercept-url pattern="/secure/**" access="IS_AUTHENTICATED_FULLY" />
<sec:custom-filter ref="spnegoAuthenticationProcessingFilter"
position="BASIC_AUTH_FILTER" />
</sec:http>
<sec:http entry-point-ref="spnegoEntryPoint" use-expressions="true" >
<sec:intercept-url pattern="/" access="permitAll" />
<sec:intercept-url pattern="/home" access="permitAll" />
<sec:intercept-url pattern="/login" access="permitAll" />
<sec:intercept-url pattern="/**" access="authenticated"/>
<sec:form-login login-page="/login" />
<sec:custom-filter ref="spnegoAuthenticationProcessingFilter"
before="BASIC_AUTH_FILTER" />
</sec:http>
<bean id="spnegoEntryPoint"
class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" />
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="kerberosAuthenticationProvider" />
<sec:authentication-provider ref="kerberosServiceAuthenticationProvider" />
</sec:authentication-manager>
<bean id="spnegoAuthenticationProcessingFilter"
class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="kerberosAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
<property name="userDetailsService" ref="dummyUserDetailsService"/>
<property name="kerberosClient">
<bean class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
<property name="debug" value="true"/>
</bean>
</property>
</bean>
<sec:authentication-manager alias="authenticationManager">
<sec:authentication-provider ref="kerberosServiceAuthenticationProvider" />
</sec:authentication-manager>
<bean id="spnegoEntryPoint"
class="org.springframework.security.extensions.kerberos.web.SpnegoEntryPoint" >
<constructor-arg value="/login" />
</bean>
<bean id="spnegoAuthenticationProcessingFilter"
class="org.springframework.security.extensions.kerberos.web.SpnegoAuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="kerberosServiceAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
<property name="ticketValidator">
<bean
class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
<property name="servicePrincipal" value="${app.service-principal}" />
<property name="keyTabLocation" value="${app.keytab-location}" />
<property name="debug" value="true" />
</bean>
</property>
<property name="userDetailsService" ref="dummyUserDetailsService" />
</bean>
<bean id="kerberosServiceAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosServiceAuthenticationProvider">
<property name="ticketValidator">
<bean
class="org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator">
<property name="servicePrincipal" value="${krb.service.prinicipal}" />
<!-- Setting keyTabLocation to a classpath resource will most likely not work in a Java EE application Server -->
<!-- See the Javadoc for more information on that -->
<property name="keyTabLocation" value="${krb.keytab.location}" />
<property name="debug" value="${krb.debug}" />
</bean>
</property>
<property name="userDetailsService" ref="dummyUserDetailsService" />
</bean>
<!-- This bean definition enables a very detailed Kerberos logging -->
<bean
class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
<property name="debug" value="${krb.debug}" />
<property name="krbConfLocation" value="${krb.conf.location}"/>
</bean>
<!--
Just returns the User authenticated by Kerberos and gives him the
ROLE_USER
-->
<bean id="dummyUserDetailsService"
class="org.springframework.security.extensions.kerberos.sample.DummyUserDetailsService" />
<context:property-placeholder location="/WEB-INF/kerberos.properties"/>
class="org.springframework.security.extensions.kerberos.docs.DummyUserDetailsService" />
</beans>
<!-- end::snippetA[] -->

View File

@@ -12,7 +12,7 @@ project('sec-server-spnego-form-auth') {
description = 'Security Server Spnego and Form Auth Sample'
}
project('sec-server-spnego-form-auth') {
project('sec-server-spnego-form-auth-xml') {
description = 'Security Server Spnego and Form Auth Xml Sample'
}