org.apache.syncope.core.spring.security.SyncopeAuthenticationProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.syncope.core.spring.security.SyncopeAuthenticationProvider.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.syncope.core.spring.security;

import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.AuditElements;
import org.apache.syncope.common.lib.types.AuditElements.Result;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.core.spring.security.AuthContextUtils.Executable;
import org.apache.syncope.core.persistence.api.entity.Domain;
import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;

@Configurable
public class SyncopeAuthenticationProvider implements AuthenticationProvider {

    protected static final Logger LOG = LoggerFactory.getLogger(SyncopeAuthenticationProvider.class);

    @Autowired
    protected AuthDataAccessor dataAccessor;

    @Autowired
    protected UserProvisioningManager provisioningManager;

    @Resource(name = "adminUser")
    protected String adminUser;

    @Resource(name = "anonymousUser")
    protected String anonymousUser;

    protected String adminPassword;

    protected String adminPasswordAlgorithm;

    protected String anonymousKey;

    protected UserDetailsService userDetailsService;

    protected final Encryptor encryptor = Encryptor.getInstance();

    /**
     * @param adminPassword the adminPassword to set
     */
    public void setAdminPassword(final String adminPassword) {
        this.adminPassword = adminPassword;
    }

    /**
     * @param adminPasswordAlgorithm the adminPasswordAlgorithm to set
     */
    public void setAdminPasswordAlgorithm(final String adminPasswordAlgorithm) {
        this.adminPasswordAlgorithm = adminPasswordAlgorithm;
    }

    /**
     * @param anonymousKey the anonymousKey to set
     */
    public void setAnonymousKey(final String anonymousKey) {
        this.anonymousKey = anonymousKey;
    }

    public void setUserDetailsService(final UserDetailsService syncopeUserDetailsService) {
        this.userDetailsService = syncopeUserDetailsService;
    }

    @Override
    public Authentication authenticate(final Authentication authentication) {
        String domainKey = SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).getDomain();
        if (StringUtils.isBlank(domainKey)) {
            domainKey = SyncopeConstants.MASTER_DOMAIN;
        }
        SyncopeAuthenticationDetails.class.cast(authentication.getDetails()).setDomain(domainKey);

        Boolean authenticated;
        if (anonymousUser.equals(authentication.getName())) {
            authenticated = authentication.getCredentials().toString().equals(anonymousKey);
        } else if (adminUser.equals(authentication.getName())) {
            if (SyncopeConstants.MASTER_DOMAIN.equals(domainKey)) {
                authenticated = encryptor.verify(authentication.getCredentials().toString(),
                        CipherAlgorithm.valueOf(adminPasswordAlgorithm), adminPassword);
            } else {
                final String domainToFind = domainKey;
                authenticated = AuthContextUtils.execWithAuthContext(SyncopeConstants.MASTER_DOMAIN,
                        new Executable<Boolean>() {

                            @Override
                            public Boolean exec() {
                                Domain domain = dataAccessor.findDomain(domainToFind);

                                return encryptor.verify(authentication.getCredentials().toString(),
                                        domain.getAdminCipherAlgorithm(), domain.getAdminPwd());
                            }
                        });
            }
        } else {
            final Pair<String, Boolean> authResult = AuthContextUtils.execWithAuthContext(domainKey,
                    new Executable<Pair<String, Boolean>>() {

                        @Override
                        public Pair<String, Boolean> exec() {
                            return dataAccessor.authenticate(authentication);
                        }
                    });
            authenticated = authResult.getValue();
            if (authenticated != null && !authenticated) {
                AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {

                    @Override
                    public Void exec() {
                        provisioningManager.internalSuspend(authResult.getKey());
                        return null;
                    }
                });
            }
        }

        final boolean isAuthenticated = authenticated != null && authenticated;
        UsernamePasswordAuthenticationToken token;
        if (isAuthenticated) {
            token = AuthContextUtils.execWithAuthContext(domainKey,
                    new Executable<UsernamePasswordAuthenticationToken>() {

                        @Override
                        public UsernamePasswordAuthenticationToken exec() {
                            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
                                    authentication.getPrincipal(), null,
                                    userDetailsService.loadUserByUsername(authentication.getPrincipal().toString())
                                            .getAuthorities());
                            token.setDetails(authentication.getDetails());

                            dataAccessor.audit(AuditElements.EventCategoryType.LOGIC,
                                    AuditElements.AUTHENTICATION_CATEGORY, null, AuditElements.LOGIN_EVENT,
                                    Result.SUCCESS, null, isAuthenticated, authentication,
                                    "Successfully authenticated, with entitlements: " + token.getAuthorities());
                            return token;
                        }
                    });

            LOG.debug("User {} successfully authenticated, with entitlements {}", authentication.getPrincipal(),
                    token.getAuthorities());
        } else {
            AuthContextUtils.execWithAuthContext(domainKey, new Executable<Void>() {

                @Override
                public Void exec() {
                    dataAccessor.audit(AuditElements.EventCategoryType.LOGIC, AuditElements.AUTHENTICATION_CATEGORY,
                            null, AuditElements.LOGIN_EVENT, Result.FAILURE, null, isAuthenticated, authentication,
                            "User " + authentication.getPrincipal() + " not authenticated");
                    return null;
                }
            });

            LOG.debug("User {} not authenticated", authentication.getPrincipal());

            throw new BadCredentialsException("User " + authentication.getPrincipal() + " not authenticated");
        }

        return token;
    }

    @Override
    public boolean supports(final Class<? extends Object> type) {
        return type.equals(UsernamePasswordAuthenticationToken.class);
    }
}