Включение ведения журнала для Spring Social
У меня есть приложение Spring MVC, которое использует Spring Social Facebook для включения входа в Facebook. Это нормально работает на моей локальной машине, но в настоящее время не работает в моей промежуточной среде. Моя проблема в том, что я не могу понять, что идет не так. Когда я пытаюсь войти в систему, меня перенаправляют на Facebook, чтобы авторизовать приложение. Эта часть отлично работает. Но когда я даю разрешение на приложение, все, что происходит, это то, что меня перенаправляют обратно на http://example.com/signin?error=provider#_=_
, который дает 404 Not Found
ошибка.
Это не очень полезно для отладки источника ошибки, и, просматривая мои файлы журнала Tomcat, я не могу найти никакой информации, которая могла бы помочь мне найти ошибку. Нет следов стека, сообщений об ошибках и т.п. Я включил log4j в своем проекте, но я не вижу никаких журналов из Spring Social. На самом деле я не уверен, как настроить ведение журнала для Spring Social, но я попробовал следующее в моем файле log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.example" level="trace">
<AppenderRef ref="Console" />
</Logger>
<Logger name="org.springframework.social" level="all">
<AppenderRef ref="Console" />
</Logger>
<Logger name="org.springframework.social.facebook" level="all">
<AppenderRef ref="Console" />
</Logger>
<Logger name="org.springframework.social.security" level="all">
<AppenderRef ref="Console" />
</Logger>
<Root level="error">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Однако я не вижу никаких журналов Spring Social в своей консоли. Ведение журнала работает нормально, если я пишу в свое приложение, как показано ниже, поэтому ведение журнала должно работать нормально.
@Controller
public class IndexController {
private static Logger logger = LogManager.getLogger(IndexController.class);
@RequestMapping("/")
public String home() {
logger.debug("Hello there from logger!");
return "home";
}
}
Как настроить ведение журнала для Spring Social? Я нашел несколько примеров, которые настраивают log4j так, как я это делаю (например, тот, который используется для тестов Spring Social), но в остальном ничего. Я предполагаю, что библиотека поддерживает это, потому что иначе я не знаю, как отлаживать ошибки. Или есть какой-нибудь другой способ узнать, что вызывает ошибку?
Ниже моя конфигурация Spring Social, хотя я не думаю, что это имеет значение в этом случае.
@Configuration
public class SocialConfig {
@Autowired
private DataSource dataSource;
@Autowired
private TextEncryptor textEncryptor;
@Autowired
private AccountService accountService;
@Autowired
private AccountRepository accountRepository;
@Value("${facebook.app.id}")
private String facebookAppId;
@Value("${facebook.app.secret}")
private String facebookAppSecret;
@Bean
public ProviderSignInController providerSignInController() {
ProviderSignInController controller = new ProviderSignInController(this.connectionFactoryLocator(), this.usersConnectionRepository(), new SpringSecuritySignInAdapter(this.accountRepository));
controller.addSignInInterceptor(new RedirectToPreviousPageInterceptor(controller));
return controller;
}
@Bean
public ConnectionFactoryRegistry connectionFactoryLocator() {
ConnectionFactoryRegistry connectionFactoryRegistry = new ConnectionFactoryRegistry();
List<ConnectionFactory<?>> connectionFactories = new ArrayList<ConnectionFactory<?>>();
connectionFactories.add(this.facebookConnectionFactory());
connectionFactoryRegistry.setConnectionFactories(connectionFactories);
return connectionFactoryRegistry;
}
@Bean
public FacebookConnectionFactory facebookConnectionFactory() {
FacebookConnectionFactory connectionFactory = new FacebookConnectionFactory(this.facebookAppId, this.facebookAppSecret);
connectionFactory.setScope("email");
return connectionFactory;
}
@Bean
public JdbcUsersConnectionRepository usersConnectionRepository() {
JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(this.dataSource, this.connectionFactoryLocator(), this.textEncryptor);
repository.setConnectionSignUp(this.accountService);
return repository;
}
}
Заранее большое спасибо.
1 ответ
Мне удалось решить эту проблему после многих проб и ошибок. Оказалось, что зависимости моего проекта были неверными, и запись в журнале Spring Framework не была правильно отправлена в log4j через slf4j. Я использовал следующие зависимости Maven:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.2</version>
</dependency>
Затем я включил ведение журнала для Spring Framework с log4j2.xml
Написал в вопросе, и похоронен в миллиард журналов, я нашел следующее:
ERROR org.springframework.social.connect.web.ProviderSignInController - Exception while completing OAuth 2 connection:
java.lang.IllegalArgumentException: Unable to initialize due to invalid secret key
at org.springframework.security.crypto.encrypt.CipherUtils.initCipher(CipherUtils.java:110) ~[spring-security-core-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.crypto.encrypt.AesBytesEncryptor.encrypt(AesBytesEncryptor.java:65) ~[spring-security-core-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.security.crypto.encrypt.HexEncodingTextEncryptor.encrypt(HexEncodingTextEncryptor.java:36) ~[spring-security-core-3.2.5.RELEASE.jar:3.2.5.RELEASE]
at org.springframework.social.connect.jdbc.JdbcConnectionRepository.encrypt(JdbcConnectionRepository.java:236) ~[spring-social-core-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.social.connect.jdbc.JdbcConnectionRepository.addConnection(JdbcConnectionRepository.java:167) ~[spring-social-core-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository.findUserIdsWithConnection(JdbcUsersConnectionRepository.java:89) ~[spring-social-core-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.social.connect.web.ProviderSignInController.handleSignIn(ProviderSignInController.java:260) ~[spring-social-web-1.1.0.RELEASE.jar:1.1.0.RELEASE]
at org.springframework.social.connect.web.ProviderSignInController.oauth2Callback(ProviderSignInController.java:217) [spring-social-web-1.1.0.RELEASE.jar:1.1.0.RELEASE]
...
Caused by: java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1034) ~[?:1.8.0_20]
at javax.crypto.Cipher.implInit(Cipher.java:800) ~[?:1.8.0_20]
at javax.crypto.Cipher.chooseProvider(Cipher.java:859) ~[?:1.8.0_20]
at javax.crypto.Cipher.init(Cipher.java:1370) ~[?:1.8.0_20]
at javax.crypto.Cipher.init(Cipher.java:1301) ~[?:1.8.0_20]
at org.springframework.security.crypto.encrypt.CipherUtils.initCipher(CipherUtils.java:105) ~[spring-security-core-3.2.5.RELEASE.jar:3.2.5.RELEASE]
... 85 more
Как видите, это вызвано слишком большой длиной ключа, поскольку JDK по умолчанию поддерживает только 128-битное шифрование из-за политики. Чтобы решить эту проблему, я последовал совету из этого ТАКОГО вопроса. Это объяснено в моих деталях в этом превосходном сообщении в блоге. Для OS X, JAVA_HOME
я сидела /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
, поэтому вы должны вставить файлы в /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/jre/lib/security
, Эта проблема возникла, потому что я использовал noOpText
текстовый шифратор на моей машине для разработки, и когда я переместил свое приложение в промежуточную среду, я настроил приложение на использование шифруемого текстового шифрования. Убедившись, что длина ключа больше не ограничена 128 битами, мне пришлось увеличить длину моего userconnection
таблицы accesstoken
столбец к varchar(255)
, Это оно! Теперь это работает правильно.
Я надеюсь, что это помогает кому-то в подобной ситуации.