知識庫 / Spring / Spring Security RSS 訂閱

Spring Social 輔助 Facebook 登錄

Spring Security
HongKong
6
02:44 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將重點介紹如何將新的 Facebook 登錄功能添加到現有的表單登錄應用程序中。

我們將使用 Spring Social 支持與 Facebook 交互,並保持代碼簡潔易懂。

注意: Spring Social 庫已棄用;我們可以查看 Spring Security 5 – OAuth2 Login,它提供基於 OAuth2 的社交登錄功能。

2. Maven 配置

首先,我們需要將 <em >spring-social-facebook</em> 依賴添加到我們的 <em >pom.xml</em> 中:

<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 {
    
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public AuthenticationManager authManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
            .userDetailsService(userDetailsService)
            .and()
            .build();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf()
            .disable()
            .authorizeRequests()
            .antMatchers("/login*", "/signin/**", "/signup/**")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
            .logout();
        return http.build();
    }
}

我們不會花太多時間來解釋這個配置——如果您想更好地理解它,請查看“表單登錄”文章。

4. Facebook 屬性

接下來,讓我們在我們的 application.properties 文件中配置 Facebook 屬性:

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

請注意:

  • 我們需要創建一個 Facebook 應用以獲取 appIdappSecret
  • 從 Facebook 應用設置中,請確保添加平台“網站”以及 http://localhost:8080/ 作為“站點 URL”

5. 安全配置 – 添加 Facebook

現在,讓我們添加一種通過 Facebook 進行系統身份驗證的新方式:

public class SecurityConfig {

    @Autowired
    private FacebookConnectionSignup facebookConnectionSignup;

    @Value("${spring.social.facebook.appSecret}")
    String appSecret;
    
    @Value("${spring.social.facebook.appId}")
    String appId;
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
        .antMatchers("/login*","/signin/**","/signup/**").permitAll()
        ...
        return http.build();
    } 

    @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 認證,這需要兩件事:
    首先,將 ConnectionFactoryLocator 註冊為 FacebookConnectionFactory,並使用我們在前面定義的 Facebook 屬性。
    其次,一個 InMemoryUsersConnectionRepository
  • 通過向 “signin/facebook” 發送 POST 請求 – 這個控制器將使用 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 登錄的用户將擁有 FACEBOOK_USER 角色,而使用表單登錄的用户將擁有 USER 角色。

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. 前端 (Front End)

最後,讓我們來審視一下我們的前端。

現在,我們將為登錄頁面提供對這兩種身份驗證流程的支持——表單登錄和 Facebook。

<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>
<p>最後 – 這是 <em >index.html</em>:</p>
<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>

請注意,此索引頁面顯示了用户名和權限信息。

這就是全部——現在我們有了兩種方式來對應用程序進行身份驗證。

9. 結論

在本文中,我們學習瞭如何使用 spring-social-facebook 來為我們的應用程序實現輔助身份驗證流程。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.