为 Spring 社交启用日志记录
Enabling logging for 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 社交日志。如果我像下面这样在我的应用程序中写入它,那么日志记录工作正常,所以日志记录应该工作正常。
@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 社交配置日志记录?我找到了一些按照我的方式配置 log4j 的示例(例如 one used for Spring Social tests),但除此之外什么都没有。我想图书馆支持这个,否则我不知道如何调试错误。或者有什么其他方法可以找出触发错误的原因吗?
以下是我的 Spring 社交配置,尽管我认为这在这种情况下并不重要。
@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;
}
}
非常感谢您。
经过反复试验,我设法解决了这个问题。原来是我的项目依赖不正确,Spring Framework 的日志没有通过 slf4j 正确发送到 log4j。我使用了以下 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>
然后我使用问题中发布的 log4j2.xml
为 Spring 框架启用了日志记录,并埋藏在十亿个日志中,我发现了以下内容:
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位加密,出于政治考虑。为了解决这个问题,我听从了 this SO question. It is explained in my details in this excellent blog post. For OS X, JAVA_HOME
is at /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
, so you would paste the files into /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/jre/lib/security
. This problem occurred because I was using a noOpText
text encryptor on my development machine, and when I moved my application to the staging environment, I had the application set up to use a querable text encryptor 的建议。在确保密钥长度不再限于 128 位之后,我不得不将 userconnection
table 的 accesstoken
列的长度增加到 varchar(255)
。而已!它现在可以正常工作了。
我希望这对处于类似情况的人有所帮助。
我有一个 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 社交日志。如果我像下面这样在我的应用程序中写入它,那么日志记录工作正常,所以日志记录应该工作正常。
@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 社交配置日志记录?我找到了一些按照我的方式配置 log4j 的示例(例如 one used for Spring Social tests),但除此之外什么都没有。我想图书馆支持这个,否则我不知道如何调试错误。或者有什么其他方法可以找出触发错误的原因吗?
以下是我的 Spring 社交配置,尽管我认为这在这种情况下并不重要。
@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;
}
}
非常感谢您。
经过反复试验,我设法解决了这个问题。原来是我的项目依赖不正确,Spring Framework 的日志没有通过 slf4j 正确发送到 log4j。我使用了以下 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>
然后我使用问题中发布的 log4j2.xml
为 Spring 框架启用了日志记录,并埋藏在十亿个日志中,我发现了以下内容:
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位加密,出于政治考虑。为了解决这个问题,我听从了 this SO question. It is explained in my details in this excellent blog post. For OS X, JAVA_HOME
is at /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
, so you would paste the files into /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/jre/lib/security
. This problem occurred because I was using a noOpText
text encryptor on my development machine, and when I moved my application to the staging environment, I had the application set up to use a querable text encryptor 的建议。在确保密钥长度不再限于 128 位之后,我不得不将 userconnection
table 的 accesstoken
列的长度增加到 varchar(255)
。而已!它现在可以正常工作了。
我希望这对处于类似情况的人有所帮助。