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

Spring Security
Remote
0
05:24 AM · Nov 30 ,2025

1. 概述

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

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

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

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

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

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

2. The Client App

讓我們從我們的客户端應用程序開始;當然,我們將使用 Spring Boot 以最小化配置:

2.1. Maven Dependencies

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


<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. Security Configuration

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

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

此配置的核心部分當然是我們在啓用單點登錄時使用的 @EnableOAuth2Sso 註解。

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

最後,我們還定義了一個 RequestContextListener 豆子來處理請求範圍。

並且是 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. Front End

現在,讓我們來看看客户端應用程序的前端配置。 我們不會在這裏專注於它,主要因為我們已經在網站上涵蓋了它。

我們的客户端應用程序在這裏有一個非常簡單的前端;這裏是 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. The Auth Server

現在我們來討論我們的授權服務器。

3.1. Maven Dependencies

首先,我們需要在我們的 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 Configuration

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

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

@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"); 
    }
}

注意我們只啓用了使用 authorization_code 授權類型的簡單客户端。

此外,注意 autoApprove 設置為 true,因此我們沒有被重定向並提示手動批准任何範圍。

3.3. Security Configuration

首先,我們禁用默認的基本身份驗證,通過我們的 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. User Endpoint

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

@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.