4

Spring Social Facebook を使用して Facebook ログインを有効にする Spring MVC アプリケーションがあります。これはローカル マシンでは問題なく動作していますが、現在、ステージング環境では動作しません。私の問題は、何がうまくいかないのか理解できないことです。ログインしようとすると、アプリケーションを承認するために 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;
    }
}

事前にどうもありがとうございました。

4

1 に答える 1

0

多くの試行錯誤の末、これを解決することができました。プロジェクトの依存関係が正しくないことが判明し、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>

次に、質問に投稿されたSpring Frameworkのロギングを有効にlog4j2.xmlし、10億のログに埋もれて、次のことがわかりました:

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 ビット暗号化のみをサポートしているためです。これを解決するために、この SO questionのアドバイスに従いました。この優れたブログ投稿で詳細に説明されています。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 ビットに制限されていないことを確認した後、テーブルの列の長さをuserconnectionaccesstokenvarchar(255). それでおしまい!正しく動作するようになりました。

これが同様の状況の誰かに役立つことを願っています。

于 2015-03-05T13:06:54.553 に答える