Spring Authorization Server (如何使用具有 PKCE 的单页应用程序进行身份验证-2)

本文主要是介绍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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/736727

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数