知識庫 / Spring / Spring Security RSS 訂閱

Spring Security OAuth2(遺留棧)簡單單點登錄

Spring Security
HongKong
5
12:53 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將討論如何使用 Spring Security OAuth 和 Spring Boot 實現 SSO – 單點登錄。

我們將使用三個獨立的應用程序:

  • 一個授權服務器 – 作為中心認證機制
  • 兩個客户端應用程序:使用 SSO 的應用程序

簡單來説,當用户嘗試訪問客户端應用程序中的受保護頁面時,他們將被重定向到首先進行身份驗證,通過授權服務器。

我們將使用 OAuth2 中的 授權碼 grant 類型來驅動身份驗證的委託。

注意:本文檔使用 Spring OAuth 遺留項目 Spring OAuth 遺留項目。對於使用 Spring Security 5 堆棧版本的本文檔,請查看我們的文章:使用 Spring Security OAuth2 實現簡單單點登錄。

2. 客户端應用

讓我們從我們的客户端應用開始,當然,我們也會使用 Spring Boot 以最大限度地減少配置:

2.1. Maven 依賴

首先,我們需要在我們的 <em pom.xml</em> 中添加以下依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security.oauth.boot</groupId>
    <artifactId>spring-security-oauth2-autoconfigure</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>

2.2. 安全配置

接下來,最重要的部分,我們的客户端應用程序的安全配置:

@Configuration
@EnableOAuth2Sso
public class UiSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/**")
          .authorizeRequests()
          .antMatchers("/", "/login**")
          .permitAll()
          .anyRequest()
          .authenticated();
    }
}

該配置的核心部分當然是 註解,我們正在使用它來啓用單點登錄。

請注意,我們需要擴展 WebSecurityConfigurerAdapter – 如果沒有它,所有路徑都會被保護,用户嘗試訪問任何頁面時都會被重定向到登錄頁面。 在我們這裏,index 和 login 頁面是唯一可以不進行身份驗證訪問的頁面。

最後,我們還定義了一個 RequestContextListener Bean 來處理請求作用域。

以及 application.yml

server:
    port: 8082
    servlet:
        context-path: /ui
    session:
      cookie:
        name: UISESSION
security:
  basic:
    enabled: false
  oauth2:
    client:
      clientId: SampleClientId
      clientSecret: secret
      accessTokenUri: http://localhost:8081/auth/oauth/token
      userAuthorizationUri: http://localhost:8081/auth/oauth/authorize
    resource:
      userInfoUri: http://localhost:8081/auth/user/me
spring:
  thymeleaf:
    cache: false

以下是一些快速説明:

  • 我們已禁用默認的基本身份驗證
  • accessTokenUri 是用於獲取訪問令牌的 URI
  • userAuthorizationUri 是用户將被重定向到的授權 URI
  • userInfoUri 是用於獲取當前用户詳細信息的用户端點 URI

此外,請注意,在我們的示例中,我們已部署了授權服務器,當然,我們也可以使用其他第三方提供商,例如 Facebook 或 GitHub。

2.3 前端

現在,讓我們來查看我們客户端應用程序的前端配置。我們這裏不會重點關注它,主要因為我們在網站上已經詳細介紹了它。

我們的客户端應用程序具有非常簡單的前端,以下是 index.html

<h1>Spring Security SSO</h1>
<a href="securedPage">Login</a>

以及 securedPage.html:

<h1>Secured Page</h1>
Welcome, <span th:text="${#authentication.name}">Name</span>

securedPage.html 頁面需要用户進行身份驗證。如果未經過身份驗證的用户嘗試訪問 securedPage.html,則會被首先重定向到登錄頁面。

3. 認證服務器

現在我們來討論一下我們的認證服務器。

3.1. Maven 依賴

首先,我們需要在我們的 pom.xml 中定義依賴項:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.3.3.RELEASE</version>
</dependency>

3.2 OAuth 配置

需要注意的是,我們將在這裏同時運行授權服務器和資源服務器,作為一個可部署的單元。

讓我們從資源服務器的配置開始——它同時也是我們的主要啓動應用程序:

@SpringBootApplication
@EnableResourceServer
public class AuthorizationServerApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(AuthorizationServerApplication.class, args);
    }
}

然後,我們將配置我們的授權服務器:

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    public void configure(
      AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.tokenKeyAccess("permitAll()")
          .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
          .withClient("SampleClientId")
          .secret(passwordEncoder.encode("secret"))
          .authorizedGrantTypes("authorization_code")
          .scopes("user_info")
          .autoApprove(true) 
          .redirectUris(
            "http://localhost:8082/ui/login","http://localhost:8083/ui2/login"); 
    }
}

請注意,我們僅使用 授權碼 grant 類型來啓用一個簡單的客户端。

此外,請注意 autoApprove 設置為 true,這樣就不會被重定向,也不會被提示手動批准任何權限範圍。

3.3. 安全配置

首先,我們將禁用默認的基本身份驗證,通過我們的 application.properties

server.port=8081
server.servlet.context-path=/auth

現在,我們來配置並定義一個簡單的表單登錄機制:

@Configuration
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatchers()
          .antMatchers("/login", "/oauth/authorize")
          .and()
          .authorizeRequests()
          .anyRequest().authenticated()
          .and()
          .formLogin().permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("john")
            .password(passwordEncoder().encode("123"))
            .roles("USER");
    }
    
    @Bean 
    public BCryptPasswordEncoder passwordEncoder(){ 
        return new BCryptPasswordEncoder(); 
    }
}

請注意,我們使用了簡單的內存式身份驗證,但可以簡單地將其替換為自定義的 userDetailsService

3.4. 用户端點

最後,我們將創建我們在配置中之前使用的用户端點:

@RestController
public class UserController {
    @GetMapping("/user/me")
    public Principal user(Principal principal) {
        return principal;
    }
}

自然,這將會返回以 JSON 格式表示的用户數據。

4. 結論

在本快速教程中,我們重點介紹了使用 Spring Security Oauth2 和 Spring Boot 實現單點登錄的方法。

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

發佈 評論

Some HTML is okay.