本文主要是介绍Spring Authorization Server (如何使用具有 PKCE 的单页应用程序进行身份验证-2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
使用 Spring Authorization Server 实现具有 PKCE 的单页应用程序进行身份验证
开启 CORS
SPA 由静态资源组成,可以通过多种方式进行部署。它可以与后端分开部署,例如使用 CDN 或单独的 Web 服务器,也可以使用 Spring Boot 与后端一起部署。
当 SPA 托管在不同的域下时,可以使用跨域资源共享 (CORS) 来允许应用程序与后端通信。
例如,如果你有一个在端口 4200 上本地运行的 Angular 开发服务器,你可以定义一个 CorsConfigurationSource @Bean并将 Spring Security 配置为允许使用 cors() DSL 的预检请求,如以下示例所示:
Enable CORS
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;@Configuration
@EnableWebSecurity
public class SecurityConfig {@Bean@Order(1)public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)throws Exception {OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0http// Redirect to the login page when not authenticated from the// authorization endpoint.exceptionHandling((exceptions) -> exceptions.defaultAuthenticationEntryPointFor(new LoginUrlAuthenticationEntryPoint("/login"),new MediaTypeRequestMatcher(MediaType.TEXT_HTML)))// Accept access tokens for User Info and/or Client Registration.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));return http.cors(Customizer.withDefaults()).build();}@Bean@Order(2)public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)throws Exception {http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())// Form login handles the redirect to the login page from the// authorization server filter chain.formLogin(Customizer.withDefaults());return http.cors(Customizer.withDefaults()).build();}@Beanpublic CorsConfigurationSource corsConfigurationSource() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.addAllowedHeader("*");config.addAllowedMethod("*");config.addAllowedOrigin("http://127.0.0.1:4200");config.setAllowCredentials(true);source.registerCorsConfiguration("/**", config);return source;}}
配置一个公共客户端
SPA 无法安全地存储凭据,因此必须将其视为公共客户端。应要求公共客户端使用代码交换证明密钥 (PKCE)。
继续前面的示例,您可以将 Spring Authorization Server 配置为使用客户端身份验证方法 none 并需要 PKCE 来支持公共客户端,如以下示例所示:
spring:security:oauth2:authorizationserver:client:public-client:registration:client-id: "public-client"client-authentication-methods:- "none"authorization-grant-types:- "authorization_code"redirect-uris:- "http://127.0.0.1:4200"scopes:- "openid"- "profile"require-authorization-consent: truerequire-proof-key: true
注意:
requireProofKey 设置在忘记包含 code_challenge 和 code_challenge_method 查询参数的情况下非常有用,因为您将收到一个错误,指示在授权请求期间需要 PKCE,而不是在令牌请求期间出现常规客户端身份验证错误。
对客户端进行身份验证
将服务器配置为支持公共客户端后,一个常见问题是:如何对客户端进行身份验证并获取访问令牌?简短的回答是:与任何其他客户一样。
SPA 是基于浏览器的应用程序,因此使用与任何其他客户端相同的基于重定向的流程。此问题通常与可以通过 REST API 执行身份验证的期望有关,而 OAuth2 并非如此。
更详细的答案需要了解 OAuth2 和 OpenID Connect 中涉及的流程,在本例中为授权代码流程。授权代码流的步骤如下:
-
客户端通过重定向到授权终结点来启动 OAuth2 请求。对于公共客户端,此步骤包括生成code_verifier和计算code_challenge,然后将其作为查询参数发送。
-
如果用户未通过身份验证,授权服务器将重定向到登录页面。身份验证后,用户将再次重定向回授权终结点。
-
如果用户尚未同意请求的范围,并且需要同意,则会显示同意页面。
-
一旦用户同意,授权服务器就会生成一个authorization_code,并通过redirect_uri重定向回客户端。
-
客户端通过查询参数获取authorization_code,并向令牌终结点执行请求。对于公共客户端,此步骤包括发送 code_verifier 参数而不是用于身份验证的凭据。
正如你所看到的,流程是相当复杂的,这只是一个概述。
这篇关于Spring Authorization Server (如何使用具有 PKCE 的单页应用程序进行身份验证-2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!