Package org.jboss.seam.security.external.openid

Source Code of org.jboss.seam.security.external.openid.OpenIdAuthenticator

package org.jboss.seam.security.external.openid;

import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletResponse;

import org.jboss.solder.logging.Logger;
import org.jboss.seam.security.AuthenticationException;
import org.jboss.seam.security.Authenticator;
import org.jboss.seam.security.BaseAuthenticator;
import org.jboss.seam.security.Identity;
import org.jboss.seam.security.external.openid.api.OpenIdPrincipal;
import org.jboss.seam.security.external.openid.api.OpenIdRelyingPartyApi;
import org.jboss.seam.security.external.openid.api.OpenIdRequestedAttribute;
import org.jboss.seam.security.external.openid.providers.OpenIdProvider;
import org.jboss.seam.security.management.picketlink.IdentitySessionProducer;
import org.jboss.seam.transaction.Transactional;
import org.picketlink.idm.api.Group;
import org.picketlink.idm.api.IdentitySession;
import org.picketlink.idm.api.Role;
import org.picketlink.idm.api.RoleType;
import org.picketlink.idm.api.User;
import org.picketlink.idm.common.exception.FeatureNotSupportedException;
import org.picketlink.idm.common.exception.IdentityException;

/**
* An Authenticator implementation that uses OpenID to authenticate the user.
*
* @author Shane Bryzak
*/
public @Named("openIdAuthenticator")
@SessionScoped
class OpenIdAuthenticator extends BaseAuthenticator implements Authenticator, Serializable {
    private static final long serialVersionUID = 4669651866032932651L;

    @Inject
    Instance<OpenIdRelyingPartyApi> openIdApiInstance;

    @Inject
    List<OpenIdProvider> providers;

    @Inject
    Logger log;

    @Inject
    HttpServletResponse response;

    @Inject
    Instance<IdentitySession> identitySession;
   
    @Inject IdentitySessionProducer identitySessionProducer;
   
    @Inject
    Identity identity;

    /**
     * If this property is set to true (the default) then user roles and attributes will be managed using the Identity
     * Management API.
     */
    private boolean identityManaged = true;

    /**
     * This code indicates which OpenID provider should be used to authenticate against. See the classes in the
     * org.jboss.seam.security.external.openid.providers package.
     */
    private String providerCode;

    public boolean isIdentityManaged() {
        return identityManaged;
    }

    public void setIdentityManaged(boolean identityManaged) {
        this.identityManaged = identityManaged;
    }

    public String getProviderCode() {
        return providerCode;
    }

    public void setProviderCode(String providerCode) {
        this.providerCode = providerCode;
    }

    protected OpenIdProvider getSelectedProvider() {
        if (providerCode != null) {
            for (OpenIdProvider provider : providers) {
                if (providerCode.equals(provider.getCode()))
                    return provider;
            }
        }
        return null;
    }

    public void authenticate() {
        OpenIdProvider selectedProvider = getSelectedProvider();
        if (selectedProvider == null) {
            throw new IllegalStateException("No OpenID provider has been selected");
        }

        OpenIdRelyingPartyApi openIdApi = openIdApiInstance.get();

        List<OpenIdRequestedAttribute> attributes = new LinkedList<OpenIdRequestedAttribute>();

        selectedProvider.requestAttributes(openIdApi, attributes);

        openIdApi.login(selectedProvider.getUrl(), attributes, getResponse());

        setStatus(AuthenticationStatus.DEFERRED);
    }

    protected HttpServletResponse getResponse() {
        return response;
    }

    public List<OpenIdProvider> getProviders() {
        return providers;
    }

    public void success(OpenIdPrincipal principal) {
        User user = new OpenIdUser(principal);
                       
        if (isIdentityManaged()) {
            // By default we set the status to FAILURE, if we manage to get to the end
            // of this method we get rewarded with a SUCCESS
            setStatus(AuthenticationStatus.FAILURE);       
        
            if (identitySessionProducer.isConfigured()) {
               validateManagedUser(principal);
            }
        }
       
        setUser(user);
        setStatus(AuthenticationStatus.SUCCESS);       
    }
   
    /**
     * Validates the OpenID user against the local Identity Management store. Important!! This method
     * must be invoked within an active transaction if you are using JpaIdentityStore (i.e., add the
     * @Transactional annotation to your authentication method).
     *
     *
     * @param principal
     */
    protected void validateManagedUser(OpenIdPrincipal principal) {
        IdentitySession session = identitySession.get();
       
        try {           
            // Check that the user's identity exists
            if (session.getPersistenceManager().findUser(principal.getIdentifier()) == null) {
                // The user wasn't found, let's create them
               
                User user = session.getPersistenceManager().createUser(principal.getIdentifier());
               
                // TODO allow the OpenID -> IDM attribute mapping to be configured
               
                // Map fetched attributes to identity-managed attributes for new users
                for (String alias : principal.getAttributeValues().keySet()) {
                    session.getAttributesManager().addAttribute(user, alias, principal.getAttribute(alias));   
                }              
               
                // Load the user's roles and groups       
                try {           
                    Collection<RoleType> roleTypes = session.getRoleManager().findUserRoleTypes(user);

                    for (RoleType roleType : roleTypes) {
                        for (Role role : session.getRoleManager().findRoles(user, roleType)) {
                            identity.addRole(role.getRoleType().getName(),
                                    role.getGroup().getName(), role.getGroup().getGroupType());
                        }
                    }
                   
                    for (Group g : session.getRelationshipManager().findAssociatedGroups(user)) {
                        identity.addGroup(g.getName(), g.getGroupType());
                    }
                } catch (FeatureNotSupportedException ex) {
                    throw new AuthenticationException("Error loading user's roles and groups", ex);
                } catch (IdentityException ex) {
                    throw new AuthenticationException("Error loading user's roles and groups", ex);
                }         
               
            }
        } catch (IdentityException ex) {
            throw new AuthenticationException("Error locating User record for OpenID user", ex);
        }    
    }
}
TOP

Related Classes of org.jboss.seam.security.external.openid.OpenIdAuthenticator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.