org.apache.cxf.fediz.spring.authentication.FederationAuthenticationProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.cxf.fediz.spring.authentication.FederationAuthenticationProvider.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.cxf.fediz.spring.authentication;

import org.apache.cxf.fediz.core.config.FedizContext;
import org.apache.cxf.fediz.core.processor.FedizProcessor;
import org.apache.cxf.fediz.core.processor.FedizProcessorFactory;
import org.apache.cxf.fediz.core.processor.FedizRequest;
import org.apache.cxf.fediz.core.processor.FedizResponse;
import org.apache.cxf.fediz.spring.FederationConfig;
import org.apache.cxf.fediz.spring.SpringFedizMessageSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.BadCredentialsException;
//import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
//import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.providers.AuthenticationProvider;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsChecker;
import org.springframework.security.userdetails.checker.AccountStatusUserDetailsChecker;
import org.springframework.util.Assert;

/**
 * This {@link AuthenticationProvider} implements the integration with the Identity Provider
 * based on the WS-Federation Passive Requestor Profile.
 */
public class FederationAuthenticationProvider
        implements AuthenticationProvider, InitializingBean, MessageSourceAware {
    private static final Logger LOG = LoggerFactory.getLogger(FederationAuthenticationProvider.class);

    protected MessageSourceAccessor messages = SpringFedizMessageSource.getAccessor();

    private AuthenticationUserDetailsService authenticationUserDetailsService;
    private FederationConfig federationConfig;

    private final UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
    //private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();

    public AuthenticationUserDetailsService getAuthenticationUserDetailsService() {
        return authenticationUserDetailsService;
    }

    public void setAuthenticationUserDetailsService(
            AuthenticationUserDetailsService authenticationUserDetailsService) {
        this.authenticationUserDetailsService = authenticationUserDetailsService;
    }

    public FederationConfig getFederationConfig() {
        return federationConfig;
    }

    public void setFederationConfig(FederationConfig federationConfig) {
        this.federationConfig = federationConfig;
    }

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(this.authenticationUserDetailsService, "An authenticationUserDetailsService must be set");
        Assert.notNull(this.messages, "A message source must be set");
        Assert.notNull(this.federationConfig, "FederationConfig cannot be null.");
    }

    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        if (!supports(authentication.getClass())) {
            return null;
        }

        if (!(authentication instanceof UsernamePasswordAuthenticationToken)) {
            return null;
        }

        // Ensure credentials are provided
        if ((authentication.getCredentials() == null) || "".equals(authentication.getCredentials())) {
            throw new BadCredentialsException(messages.getMessage(
                    "FederationAuthenticationProvider.noSignInRequest", "Failed to get SignIn request"));
        }

        FederationAuthenticationToken result = null;

        if (result == null) {
            result = this.authenticateNow(authentication);
            result.setDetails(authentication.getDetails());
        }

        return result;
    }

    private FederationAuthenticationToken authenticateNow(final Authentication authentication)
            throws AuthenticationException {
        try {
            FedizRequest wfReq = (FedizRequest) authentication.getCredentials();
            FedizContext context = federationConfig.getFedizContext();
            FedizProcessor wfProc = FedizProcessorFactory.newFedizProcessor(context.getProtocol());
            FedizResponse wfRes = wfProc.processRequest(wfReq, context);

            final UserDetails userDetails = loadUserByFederationResponse(wfRes);
            userDetailsChecker.check(userDetails);
            return new FederationAuthenticationToken(userDetails, authentication.getCredentials(),
                    userDetails.getAuthorities(), userDetails, wfRes);
        } catch (Exception e) {
            LOG.error("Failed to validate SignIn request", e);
            throw new BadCredentialsException(e.getMessage(), e);
        }
    }

    /**
     * Template method for retrieving the UserDetails based on the federation response (wresult parameter).
     *
     * @param response The WS Federation response
     * @return the UserDetails.
     */
    protected UserDetails loadUserByFederationResponse(final FedizResponse response) {
        final FederationResponseAuthenticationToken token = new FederationResponseAuthenticationToken(response);
        return this.authenticationUserDetailsService.loadUserDetails(token);
    }

    public void setMessageSource(final MessageSource messageSource) {
        this.messages = new MessageSourceAccessor(messageSource);
    }

    @Override
    public boolean supports(Class authentication) {
        if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication)) {
            return true;
        } else {
            return FederationAuthenticationToken.class.isAssignableFrom(authentication);
        }
    }

    /*
    public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) {
    this.authoritiesMapper = authoritiesMapper;
    }
    */

    /*
    public boolean supports(final Class<?> authentication) {
    return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication))
        || (FederationAuthenticationToken.class.isAssignableFrom(authentication));
    }
    */
}