1. 概要

このチュートリアルでは、既存のフォームログインアプリに新しいFacebookログインを追加することに焦点を当てます。

Springソーシャルサポートを使用してFacebookとやり取りし、物事をクリーンでシンプルに保ちます。

2. Maven構成

まず、spring-social-facebook依存関係をpom.xmlに追加する必要があります。

<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-facebook</artifactId>
    <version>2.0.3.RELEASE</version>
</dependency>

3. セキュリティ構成–フォームログインのみ

まず、フォームベースの認証がある単純なセキュリティ構成から始めましょう。

@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = { "com.baeldung.security" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) 
      throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers("/login*").permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin().loginPage("/login").permitAll();
    } 
}

この構成に多くの時間を費やすことはありません。よりよく理解したい場合は、フォームログイン記事を参照してください。

4. Facebookのプロパティ

次に、application.propertiesでFacebookのプロパティを構成しましょう。

spring.social.facebook.appId=YOUR_APP_ID
spring.social.facebook.appSecret=YOUR_APP_SECRET

ご了承ください:

  • appIdappSecretを取得するには、Facebookアプリケーションを作成する必要があります。
  • Facebookアプリケーションの設定から、プラットフォーム「Webサイト」を追加し、 http:// localhost:8080/が「サイトURL」であることを確認してください

5. セキュリティ構成–Facebookの追加

それでは、Facebookによって駆動される、システムに認証するための新しい方法を追加しましょう。

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private FacebookConnectionSignup facebookConnectionSignup;

    @Value("${spring.social.facebook.appSecret}")
    String appSecret;
    
    @Value("${spring.social.facebook.appId}")
    String appId;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
        .antMatchers("/login*","/signin/**","/signup/**").permitAll()
        ...
    } 

    @Bean
    public ProviderSignInController providerSignInController() {
        ConnectionFactoryLocator connectionFactoryLocator = 
            connectionFactoryLocator();
        UsersConnectionRepository usersConnectionRepository = 
            getUsersConnectionRepository(connectionFactoryLocator);
        ((InMemoryUsersConnectionRepository) usersConnectionRepository)
            .setConnectionSignUp(facebookConnectionSignup);
        return new ProviderSignInController(connectionFactoryLocator, 
            usersConnectionRepository, new FacebookSignInAdapter());
    }
    
    private ConnectionFactoryLocator connectionFactoryLocator() {
        ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
        registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));
        return registry;
    }
    
    private UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator 
        connectionFactoryLocator) {
        return new InMemoryUsersConnectionRepository(connectionFactoryLocator);
    }
}

新しい構成を注意深く見てみましょう。

  • ProviderSignInController を使用してFacebook認証を有効にします。これには、2つのことが必要です。1つは、前に定義したFacebookプロパティでFacebookConnectionFactoryとして登録されたConnectionFactoryLocatorです。 。 次に、InMemoryUsersConnectionRepository
  • POSTを「/signin / facebook 」に送信することにより–このコントローラーは、Facebookサービスプロバイダーを使用してユーザーサインインを開始します
  • アプリケーションのログインロジックを処理するためにSignInAdapterを設定しています
  • また、 ConnectionSignUp を設定して、ユーザーがFacebookで最初に認証するときに暗黙的にサインアップするユーザーを処理します。

6. サインインアダプタ

簡単に言えば、このアダプターは、上記のコントローラー(Facebookユーザーのサインインフローを駆動する)と特定のローカルアプリケーションの間のブリッジです。

public class FacebookSignInAdapter implements SignInAdapter {
    @Override
    public String signIn(
      String localUserId, 
      Connection<?> connection, 
      NativeWebRequest request) {
        
        SecurityContextHolder.getContext().setAuthentication(
          new UsernamePasswordAuthenticationToken(
          connection.getDisplayName(), null, 
          Arrays.asList(new SimpleGrantedAuthority("FACEBOOK_USER"))));
        
        return null;
    }
}

Facebookを使用してログインしたユーザーには役割があることに注意してくださいファイスブックユーザー 、フォームを使用してログインしたユーザーには役割がありますユーザー。

7. 接続サインアップ

ユーザーが初めてFacebookで認証するとき、ユーザーはアプリケーションに既存のアカウントを持っていません。

これは、それらのアカウントを自動的に作成する必要があるポイントです。 ConnectionSignUp を使用して、そのユーザー作成ロジックを駆動します。

@Service
public class FacebookConnectionSignup implements ConnectionSignUp {

    @Autowired
    private UserRepository userRepository;

    @Override
    public String execute(Connection<?> connection) {
        User user = new User();
        user.setUsername(connection.getDisplayName());
        user.setPassword(randomAlphabetic(8));
        userRepository.save(user);
        return user.getUsername();
    }
}

ご覧のとおり、 DisplayName をユーザー名として使用して、新しいユーザーのアカウントを作成しました。

8. フロントエンド

最後に、フロントエンドを見てみましょう。

ログインページで、フォームログインとFacebookの2つの認証フローがサポートされるようになります。

<html>
<body>
<div th:if="${param.logout}">You have been logged out</div>
<div th:if="${param.error}">There was an error, please try again</div>

<form th:action="@{/login}" method="POST" >
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" value="Login" />
</form>
	
<form action="/signin/facebook" method="POST">
    <input type="hidden" name="scope" value="public_profile" />
    <input type="submit" value="Login using Facebook"/>
</form>
</body>
</html>

最後に–これがindex.htmlです。

<html>
<body>
<nav>
    <p sec:authentication="name">Username</p>      
    <a th:href="@{/logout}">Logout</a>                     
</nav>

<h1>Welcome, <span sec:authentication="name">Username</span></h1>
<p sec:authentication="authorities">User authorities</p>
</body>
</html>

このインデックスページにユーザー名と権限がどのように表示されているかに注意してください。

これで、アプリケーションを認証する方法が2つあります。

9. 結論

この簡単な記事では、spring-social-facebookを使用してアプリケーションのセカンダリ認証フローを実装する方法を学びました。

そしてもちろん、いつものように、ソースコードはGitHubで完全に利用可能です