我正在研究Rest Api,我想在我的应用程序中实现facebook登录/注册。 我的客户端是基于angularjs的应用程序,它向facebook发送请求并获取身份验证代码,到目前为止,我使用自定义过滤器调用facebook并在验证访问令牌后获取用户数据。
我现在可以从Facebook获取用户详细信息并保留在我的本地数据库中,但是当我尝试从我的应用程序注册时,它会移动到我为facebook集成进行的自定义过滤器。这是我的SecurityConfiguration.java
package io.aurora.ams.config;
import io.aurora.ams.security.AuthoritiesConstants;
import io.aurora.ams.web.filter.MDCFilter;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import javax.inject.Inject;
import static io.aurora.ams.sharedkernel.support.RestPath.*;
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@ImportResource("classpath:acl-config.xml")
@SuppressWarnings("ALL")
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
@Bean
public AuthFilter authFilter()
{
return new AuthFilter();
}
@Inject
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean
public MDCFilter mdcFilter()
{
return new MDCFilter();
}
@Bean
public FilterRegistrationBean mySecurityFilter()
{
FilterRegistrationBean registration = new FilterRegistrationBean(authFilter());
registration.setOrder(10);
return registration;
}
@Override
public void configure(WebSecurity web) throws Exception
{
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers(API_VERSION_1_ACCOUNT_REGISTER_PATIENT)
.antMatchers(API_VERSION_1_ACCOUNT_ACTIVATE)
.antMatchers(API_VERSION_1_ACCOUNT_RECOVER_PASSWORD)
.antMatchers("/test/**")
.antMatchers("/h2-console/**");
}
@Override
@Order(Ordered.HIGHEST_PRECEDENCE)
public void configure(HttpSecurity http) throws Exception
{
http
.addFilterBefore(authFilter(), OAuth2ClientAuthenticationProcessingFilter.class)
.addFilterAfter(mdcFilter(), SecurityContextPersistenceFilter.class)
.httpBasic().realmName("pliro")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/oauth/authorize").permitAll()
.antMatchers("api/v1/auth/facebook").permitAll()
.antMatchers("api/v1/code").permitAll()
.and()
.authorizeRequests()
.antMatchers(API_VERSION_1_DOCTOR).permitAll()
.antMatchers(API + "/**").authenticated();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension()
{
return new SecurityEvaluationContextExtension();
}
}
这是我的CustomFilter AuthFilter.java
package io.aurora.ams.config;
import io.aurora.ams.account.domain.model.user.User;
import io.aurora.ams.account.dto.UserDTO;
import io.aurora.ams.account.mapper.UserMapper;
import io.aurora.ams.account.repository.UserRepository;
import io.aurora.ams.sharedkernel.domain.model.Gender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.social.InvalidAuthorizationException;
import org.springframework.social.connect.Connection;
import org.springframework.social.facebook.api.Facebook;
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.inject.Inject;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by ozair on 16/6/16.
*/
@Component
public class AuthFilter extends OncePerRequestFilter
{
@Autowired
private UserRepository userRepository;
@Autowired
private FacebookConnectionFactory facebookConnectionFactory;
@Inject
private UserMapper userMapper;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException
{
String xAuth = request.getHeader("fbToken");
try
{
User user = validateToken(xAuth);
// Create our Authentication and let Spring know about it
Authentication authentication = new UsernamePasswordAuthenticationToken(user, null, AuthorityUtils.createAuthorityList("ROLE_USER"));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
catch (InvalidAuthorizationException ex)
{
logger.error(ex.getMessage());
}
filterChain.doFilter(request, response);
}
private User validateToken(String fbToken)
{
AccessGrant accessGrant = new AccessGrant(fbToken);
Connection<Facebook> connection = facebookConnectionFactory.createConnection(accessGrant);
org.springframework.social.facebook.api.User fbUser = connection.getApi().userOperations().getUserProfile();
String facebookId = fbUser.getId();
User user = userRepository.findBySocialId(facebookId);
if (user == null)
{
User userByEmail = userRepository.findByEmail(fbUser.getEmail());
if (userByEmail != null)
{
userByEmail.setSocialAccessGrant(accessGrant.getAccessToken());
userByEmail.setSocialId(facebookId);
userRepository.save(userByEmail);
return userByEmail;
}
else
{
String firstName = fbUser.getFirstName();
String lastName = fbUser.getLastName();
String email = fbUser.getEmail() == null ? "" : fbUser.getEmail();
UserDTO userDTO = new UserDTO();
userDTO.setFirstName(firstName);
userDTO.setLastName(lastName);
userDTO.setEmail(email);
userDTO.setPassword("123456");
userDTO.setPhoneNumber("03222211112");
userDTO.setGender(Gender.MALE);
userDTO.setSocialId(facebookId);
userDTO.setAccessGrant(accessGrant);
User userData = userMapper.userDTOtoUser(userDTO);
userRepository.save(userData);
return userData;
}
}
else
{
//update fbToken if not the same
if (user.getSocialAccessGrant() != null
&& !user.getSocialAccessGrant().equals(accessGrant.getAccessToken()))
{
user.setSocialAccessGrant(accessGrant.getAccessToken());
userRepository.save(user);
}
return user;
}
}
}