001    /* Copyright 2006-2009 the original author or authors.
002     *
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *      http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software
010     * distributed under the License is distributed on an "AS IS" BASIS,
011     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     * See the License for the specific language governing permissions and
013     * limitations under the License.
014     */
015    package org.codehaus.groovy.grails.plugins.springsecurity.facebook;
016    
017    import org.springframework.beans.factory.InitializingBean;
018    import org.springframework.security.Authentication;
019    import org.springframework.security.AuthenticationException;
020    import org.springframework.security.AuthenticationServiceException;
021    import org.springframework.security.BadCredentialsException;
022    import org.springframework.security.providers.AuthenticationProvider;
023    import org.springframework.security.userdetails.UserDetails;
024    import org.springframework.security.userdetails.UserDetailsService;
025    import org.springframework.util.Assert;
026    
027    /**
028     * Finalizes the authentication process by populating the local authorities for the authenticated user.
029     *
030     * @author <a href='mailto:beckwithb@studentsonly.com'>Burt Beckwith</a>
031     */
032    public class FacebookAuthenticationProvider implements AuthenticationProvider, InitializingBean {
033    
034            private UserDetailsService _userDetailsService;
035    
036            /**
037             * {@inheritDoc}
038             * @see org.springframework.security.providers.AuthenticationProvider#authenticate(
039             *      org.springframework.security.Authentication)
040             */
041            public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
042    
043                    if (!supports(authentication.getClass()) ||
044                                    !(authentication instanceof FacebookAuthenticationToken)) {
045                            return null;
046                    }
047    
048                    FacebookAuthenticationToken token = (FacebookAuthenticationToken)authentication;
049                    FacebookAuthenticationToken.Status status = token.getStatus();
050    
051                    switch (status) {
052                            case success:
053                                    UserDetails userDetails = _userDetailsService.loadUserByUsername(String.valueOf(token.getUserId()));
054                                    return new FacebookAuthenticationToken(userDetails.getAuthorities(),
055                                                    token.getUserId(), token.getSessionKey());
056                            case failure:
057                                    throw new BadCredentialsException("Log in failed - identity could not be verified");
058                            case error:
059                                    throw new AuthenticationServiceException("Error message from server: " + token.getErrorMessage());
060                    }
061    
062                    // unreachable
063                    return null;
064            }
065    
066            /**
067             * Dependency injection for the user detail service.
068             * @param userDetailsService  the service
069             */
070            public void setUserDetailsService(final UserDetailsService userDetailsService) {
071                    _userDetailsService = userDetailsService;
072            }
073    
074       /**
075        * {@inheritDoc}
076        * @see org.springframework.security.providers.AuthenticationProvider#supports(java.lang.Class)
077        */
078       @SuppressWarnings("unchecked")
079            public boolean supports(final Class authentication) {
080           return FacebookAuthenticationToken.class.isAssignableFrom(authentication);
081       }
082    
083            /**
084             * {@inheritDoc}
085             * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
086             */
087            public void afterPropertiesSet() {
088                    Assert.notNull(_userDetailsService, "The userDetailsService must be set");
089            }
090    }