2

Я пытаюсь реализовать социальный логин для приложения загрузки весны. Я использую Spring Boot версии 1.4.2. приложение использует весеннюю безопасность, поэтому я решил использовать аннотацию @EnableOAuthSso на WebSecurityConfigurerAdapter. Я использую Facebook в качестве поставщика OAuthРеализовать PrincipalExtractor для facebook (весенний ботинок с социальным)

мои application.properties выглядит следующим образом:

spring.social.facebook.appId=12345678976543 
spring.social.facebook.appSecret=a4179c05880d948cd6c05806a4179d7c 
security.oauth2.client.client-id= 12345678976543 
security.oauth2.client.client-secret= a4179c05880d948cd6c05806a4179d7c 
security.oauth2.client.access-token-uri= https://graph.facebook.com/oauth/access_token 
security.oauth2.client.user-authorization-uri= https://www.facebook.com/dialog/oauth 
security.oauth2.client.token-name= oauth_token 
security.oauth2.client.authentication-scheme= query 
security.oauth2.client.client-authentication-scheme= form 
security.oauth2.resource.user-info-uri= https://graph.facebook.com/me 

Рекомендуемый способ установки principal является реализация интерфейса PrincipalExtractor.

Мой Immplementation выглядит следующим образом:

@Bean 
public PrincipalExtractor principalExtractor(Facebook facebook, UserRepository userRepository) { 
    return new PrincipalExtractor() { 
     @Override 
     public Object extractPrincipal(Map<String, Object> map) { 
      String facebookId = (String) map.get("id");  
      User u= userRepository.findByFacebookId(facebookId); 

      if (u== null) { 
       org.springframework.social.facebook.api.User user = facebook.userOperations().getUserProfile(facebookId); 
       u= new User(); 
       u.setEmail(user.getEmail()); 
       u.setFirstName(user.getFirstName()); 
       u.setLastName(user.getLastName()); 
       u.setFacebookId(facebookId); 
       userRepository.save(u); 
      } 
      return u; 
     } 
    }; 

При запуске этого он перенаправляет пользователя на страницу авторизации facebook, но когда facebook перенаправляет обратно в приложение (Это где PrincipalExtractor # extractPrincipal вызывается) линия:

org.springframework.social.facebook.api.User user = facebook.userOperations().getUserProfile(facebookId); 

бросить следующее исключение:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.facebook' defined in class path resource [org/springframework/boot/autoconfigure/social/FacebookAutoConfiguration$FacebookConfigurerAdapter.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.social.facebook.api.Facebook]: Factory method 'facebook' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.connectionRepository' defined in class path resource [org/springframework/social/config/annotation/SocialConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.social.connect.ConnectionRepository]: Factory method 'connectionRepository' threw exception; nested exception is java.lang.IllegalStateException: Unable to get a ConnectionRepository: no user signed in 
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1022) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:345) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:44) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192) ~[spring-aop-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at com.sun.proxy.$Proxy81.userOperations(Unknown Source) ~[na:na] 
at org.commerceforge.estore.config.SocialSecurityConfig$2.extractPrincipal(SocialSecurityConfig.java:115) ~[main/:na] 
at org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices.getPrincipal(UserInfoTokenServices.java:115) ~[spring-boot-autoconfigure-1.4.2.RELEASE.jar:1.4.2.RELEASE] 
at org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices.extractAuthentication(UserInfoTokenServices.java:97) ~[spring-boot-autoconfigure-1.4.2.RELEASE.jar:1.4.2.RELEASE] 
at org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices.loadAuthentication(UserInfoTokenServices.java:93) ~[spring-boot-autoconfigure-1.4.2.RELEASE.jar:1.4.2.RELEASE] 
at org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationProcessingFilter.java:112) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na] 
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) ~[spring-security-web-4.1.3.RELEASE.jar:4.1.3.RELEASE] 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter.doFilter(OAuth2ClientContextFilter.java:60) ~[spring-security-oauth2-2.0.12.RELEASE.jar:na] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:164) ~[spring-session-1.2.2.RELEASE.jar:na] 
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) ~[spring-session-1.2.2.RELEASE.jar:na] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:107) ~[spring-boot-actuator-1.4.2.RELEASE.jar:1.4.2.RELEASE] 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.6.jar:8.5.6] 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.6.jar:8.5.6] 
at 

org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.6.jar:8.5.6] 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.6.jar:8.5.6] 
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) [tomcat-embed-core-8.5.6.jar:8.5.6] 
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.6.jar:8.5.6] 
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) [tomcat-embed-core-8.5.6.jar:8.5.6] 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) [tomcat-embed-core-8.5.6.jar:8.5.6] 
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.6.jar:8.5.6] 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_101] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_101] 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.6.jar:8.5.6] 
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_101] 
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.social.facebook.api.Facebook]: Factory method 'facebook' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.connectionRepository' defined in class path resource [org/springframework/social/config/annotation/SocialConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.social.connect.ConnectionRepository]: Factory method 'connectionRepository' threw exception; nested exception is java.lang.IllegalStateException: Unable to get a ConnectionRepository: no user signed in 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] 
    ... 80 common frames omitted 

Это означает, что фреймворк не может создать bean-элемент Facebook, потому что в нем нет пользователя!

Это происходит после того, как пользователь авторизует заявку на сайте facebook и перенаправляется обратно в мое приложение, поэтому теоретически существует подписанный пользователь, я точно не знаю, как и когда структура получает эту информацию.

Это, как я реализовал его, не уверен, что это неправильно,

Пожалуйста, дайте мне знать, как реализовать это право, чтобы получить данные профиля пользователя (org.springframework.social.facebook.api.User)

Что является рекомендуемым способом реализации PrincipalExtractor для Facebook?

Благодаря

ответ

1

Здравствуйте, я знаю, что это 2 monhts старой, но, может быть, кто-то найдет пост ищет аналогичный ответ

Причины вы получили это исключение, потому что весна социального соединение отличается, чем вы используете присягу. Что вам нужно, это выглядит следующим образом: Получить фишку от существующего соединения с аутентификацией (конечно закрепить InstanceOf и т.д.)

Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
String token = ((OAuth2AuthenticationDetails) authentication.getDetails()).getTokenValue(); 

И тогда вы можете получить данные с spring.social.facebook, как это:

Facebook facebook = new FacebookTemplate(token); 
if (facebook.isAuthorized()) { 
     String[] fields = {"id", "email", "first_name", "last_name", "cover"}; 
     User userProfile = facebook.fetchObject("me", User.class, fields); 
     byte[] userProfileImage = facebook.userOperations().getUserProfileImage(); 
     //rest of stuff 
    } 

Надеюсь, это поможет

+0

'getAuthentication()' на самом деле для меня в этом случае используется при использовании в PrincipalExtractor - любая идея, почему это может быть? – bvulaj

+0

Если 'getAuthentication()' равно null, убедитесь, что ваша конфигурация безопасности весна верна, и вы действительно правильно входите в систему с OAuth. Значение аутентификации в контексте безопасности должно быть не менее AnonymousAuthentication – Khobar

+0

Выяснил проблему. Когда вы устанавливаете mainExtractor вручную в tokenService, экстрактор вызывается во время создания объекта Authentication. Решение состоит в том, чтобы вместо этого ввести OAuth2ClientContext и вместо этого получить токен. – bvulaj

1

В некоторых случаях объект проверки подлинности может быть недоступен. Вместо этого вы можете ввести OAuth2ClientContext и получить токен, который вам нужен, чтобы получить доступ к поставщику удостоверений, в этом случае Facebook.

@Autowired 
private OAuth2ClientContext oAuth2ClientContext; 
... 
String token = oAuth2ClientContext.getAccessToken().getValue(); 
Facebook fbApi = new FacebookTemplate(token);