Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Spring Security Plugin

...

Apache CXF Fediz ships three different plugins for Spring Security - supporting Spring Security 2, 3 and 4.

This page describes how to enable Federation for a Spring Security based Web Application. Also note that from the 1.4.5 release, the Spring 3 and 4 plugins also support SAML SSO. Spring Security provide provides more authorization capabilities than defined in the Java Servlet specification. Beyond authorizing web requests Spring Security supports authorizing whether methods can be invoked and authorizing access to individual domain object instances. Further,

Spring Security supports two deployment options. This configuration is not for a separate Tomcat instance hosting the Fediz IDP and IDP STS WARs, or hosts for third-party applications that use Fediz STS-generated SAML assertions for authentication. After this configuration is done, the Jetty-RP instance will validate the incoming SignInResponse created by the IDP server.On the one hand, authentication and authorization is enforced by the underlying Servlet Container or on the other hand by Spring Security embedded with the application. The former ensures that the application is only called if authentication is successful. This can be controlled by an administrator/operator. This option is called Pre-Authentication. The latter gives all the control to the application developer and removes the dependency to security configuration in the Servlet Container. This simplifies deploying an application into different Serlvet Container environments.

Both options are valid and it mainly depends on the policies/requirements within a company which is a better fit. Questions to be answered are: Who should manage the security enforcement (Application developer, Administrator)? Do you have to deploy the application into different Servlet Container environments?

Prior to doing this configuration, make sure you've first deployed the Fediz IDP and STS on the Tomcat IDP instance as discussed here, and can view the STS WSDL at the URL given on that page. That page also provides some tips for running multiple Tomcat instances on your machine.

Installation

You can either build the Fediz plugin on your own or , download the package here or add the dependency to your Maven project. If you have built the plugin on your own you'll find the required libraries in plugins/jettyspring/target/...zip-with-dependencies.zip

  1. Create sub-directory fediz in ${jetty.home}/lib/fediz
  2. Update start.ini in ${jetty.home}/start.ini by adding fediz to the OPTIONS
    Code Block
    
    OPTIONS=Server,fediz
    
  3. Deploy the libraries to the directory created in (1)

Configuration

HTTPS configuration

It's recommended to set up a dedicated (separate) Jetty instance for the Relying Party. The Fediz RP web applications use the following TCP ports:

  • HTTP port: 8080
  • HTTPS port: 8443 (where IDP and STS are accessed)

These are the default ports for a standard Jetty installation.

The Relying Party must be accessed over HTTPS to protect the security tokens issued by the IDP.

The Jetty HTTP(s) configuration is done in etc/jetty-ssl.xml.

The configuration is described in detail here

This page also describes how to create certificates. Sample Jetty keystores (not for production use, but useful for demoing Fediz and running the sample applications) are provided in the examples/samplekeys folder of the Fediz distribution. Note the Jetty keystore here is different from the one used to configure the Tomcat-IDP instance.

To establish trust, there are significant keystore/truststore requirements between the Servlet Container instances and the various web applications (IDP, STS, Relying party applications, third party web services, etc.) See this page for more details, it lists the trust requirements as well as sample scripts for creating your own (self-signed) keys.

Warning: All sample keystores provided with Fediz (including in the WAR files for its services and examples) are for development/prototyping use only. They'll need to be replaced for production use, at a minimum with your own self-signed keys but strongly recommended to use third-party signed keys.

It's recommended to use Maven to resolve all the dependencies as illustrated in the two examples springWebapp and springPreAuthWebapp. Each example contains a README with instructions for building and deployment.

Web Application with Pre-Authentication Spring Security

The role of the Fediz Spring plugin in the case of Servlet Container managed security is to adapt the security context of the Servlet Container to the Spring Security Context. This allows to configure authorization for web requests and method calls based on Spring Security.

This deployment option requires to configure Fediz into the Servlet Container which is described here:

Fediz Plugin configuration for Your Web Application

The Fediz related configuration is done in a Servlet Container independent configuration file which is described here.

Spring Security Configuration

The following configuration snippets illustrate the Fediz related configuration. The complete configuration file can be found in the example springPreAuthWebapp.

Code Block
xml
xml
borderStylesolid
titleapplicationContext-security.xml


    <bean id="preAuthenticatedUserDetailsService"
            class="org.apache.cxf.fediz.spring.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsFederationService"/>    
    
    <bean id="j2eePreAuthFilter" class="org.apache.cxf.fediz.spring.preauth.FederationPreAuthenticatedProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationDetailsSource">
            <bean class="org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource">
                <property name="mappableRolesRetriever">
                    <bean class="org.springframework.security.web.authentication.preauth.j2ee.WebXmlMappableAttributesRetriever" />
                </property>
                <property name="userRoles2GrantedAuthoritiesMapper">
                    <bean class="org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper">
                        <property name="convertAttributeToUpperCase" value="true"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

    <bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
        <property name="securityMetadataSource">
            <sec:filter-invocation-definition-source>
                <sec:intercept-url pattern="/secure/manager/**" access="ROLE_MANAGER"/>
                <sec:intercept-url pattern="/secure/admin/**" access="ROLE_ADMIN"/>
                <sec:intercept-url pattern="/secure/user/**" access="ROLE_USER,ROLE_ADMIN,ROLE_MANAGER"/>
                <sec:intercept-url pattern="/secure/fedservlet" access="ROLE_USER,ROLE_ADMIN,ROLE_MANAGER,ROLE_AUTHENTICATED"/>
            </sec:filter-invocation-definition-source>
        </property>
    </bean>

The beans preAuthenticatedUserDetailsService and j2eePreAuthFilter are required to provide the Fediz related security information (claims, login token) to the Spring Security Context. The bean fsi defines the authorization for the web requests which looks similar to security constraints definition in web.xml.

The following code snippet of the FederationServlet example illustrates how to get access to the Spring Security Context of the current user.

Code Block
borderStylesolid
titleFederationServlet.java

    Authentication obj = SecurityContextHolder.getContext().getAuthentication();

The Authentication object can be casted to the FederationAuthentiationToken which provides access to Claims, login token, etc.

Web Application with "native" Spring Security

In this case, authentication and authorization are managed by Spring Security only. The Fediz Spring Plugin provides the implementation of WS-Federation by implementing certain Spring Security interfaces. Finally, this results into the creation of the Spring Security Context. You can use Spring's authorization capabilities for web requests and method calls. The example springWebapp only illustrates authorizing web requests. Method based authorization is described hereIf you are currently just trying to run the Fediz samples, the configuration above is all you need (the below configuration is already provided within the samples) so you can return now to the samples' READMEs for the next steps in running them.

Fediz Plugin configuration for Your Web Application

The Fediz related configuration is done in a Servlet Container independent configuration file which is described here.

Spring Security Configuration

The Fediz plugin requires configuring the FederationAuthenticator like any other authenticator in Jetty. Detailed information about the Authenticators and SecurityHandler is available here.

The Fediz configuration file allows to configure all servlet contexts in one file or choosing one file per Servlet Context.

You can configure the context in context configuration file located in <jetty.home>/contexts.

...

fedizhelloworld.xml

...

Hint: file name must be equal to war file name

following configuration snippets illustrate the Fediz related configuration. The complete configuration file can be found in the example springWebapp.

Code Block
xml
xml
borderStylesolid
titleapplicationContext-security.xml

    <sec:http entry-point-ref="federationEntryPoint" use-expressions="true">
        <sec:intercept-url pattern="/" access="permitAll"/>
        <sec:intercept-url pattern="/fediz" access="permitAll"/>
        <sec:intercept-url pattern="/index.html" access="permitAll"/>
        <sec:intercept-url pattern="/secure/fedservlet" access="isAuthenticated()"/>
        <sec:intercept-url pattern="/secure/manager/**" access="hasRole('ROLE_MANAGER')"/>
        <sec:intercept-url pattern="/secure/admin/**" access="hasRole('ROLE_ADMIN')"/>
        <sec:intercept-url pattern="/secure/user/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN','ROLE_MANAGER')"/>
        <sec:custom-filter ref="federationFilter" after="BASIC_AUTH_FILTER" />
        <sec:session-management session-authentication-strategy-ref="sas"/>
    </sec:http>

    <sec:authentication-manager alias="authManager">
        <sec:authentication-provider ref="federationAuthProvider" />
    </sec:authentication-manager>

    <bean id="fedizConfig"
Code Block
xmlxml
 
  <Get name="securityHandler">
    <Set name="loginService">
      <New class="org.apache.cxf.fediz.jetty.FederationLoginService">spring.FederationConfigImpl" init-method="init"
        p:configFile="WEB-INF/fediz_config.xml" />

    <Set<bean nameid="namefederationEntryPoint">WSFED</Set>
        </New>
    </Set>class="org.apache.cxf.fediz.spring.web.FederationAuthenticationEntryPoint"
        p:federationConfig-ref="fedizConfig" />
 
    <Set<bean nameid="authenticatorfederationFilter">
       <New class="org.apache.cxf.fediz.jettyspring.web.FederationAuthenticatorFederationAuthenticationFilter">
        <Set namep:authenticationManager-ref="configFile"><SystemPropertyauthManager">
        <property name="jetty.home" default="."/>/etc/fediz_config.xml</Set>
authenticationFailureHandler">
            <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" />
        </property>
    </bean>
    
    <bean id="federationAuthProvider" class="org.apache.cxf.fediz.spring.authentication.FederationAuthenticationProvider"
        p:federationConfig-ref="fedizConfig">
        <property name="authenticationUserDetailsService">
            </New>
 <bean class="org.apache.cxf.fediz.spring.authentication.GrantedAuthoritiesUserDetailsFederationService"/>
        </Set>property>
    </Get>bean>

The Fediz configuration file is a Servlet container independent configuration file and described here

Web Application deployment

...

http element is the key element which depends on the other bean definitions like federationFilter and the federationAuthProvider. Web request authorizing is configured in the http element as well which looks similar to security constraints definition in web.xml.

The following code snippet of the FederationServlet example illustrates how to get access to the Spring Security Context of the current user and to the Federation releated information like claims and login token.

Code Block
borderStylesolid
titleFederationServlet.java

    Authentication obj = SecurityContextHolder.getContext().getAuthentication();
    FederationAuthenticationToken fedAuthToken = (FederationAuthenticationToken)auth;
    for (GrantedAuthority item : fedAuthToken.getAuthorities()) {
        ...
    }
    
    ClaimCollection claims = ((FederationUser)fedAuthToken.getUserDetails()).getClaims();
    for (Claim c: claims) {
        ...
    }

Federation Metadata document

The Jetty Spring Security Fediz plugin supports publishing the WS-Federation Metadata document which is described here.