spring authorization server 0.3.1 - 默认示例

article/2025/10/12 9:06:29

spring authorization server 0.3.1 - 默认oidc

  • 开始
    • 1、default-authorizationserver项目
      • 1.1、AuthorizationServerConfig.java
      • 1.2、DefaultSecurityConfig.java
      • 1.3、Jwks.java
      • 1.4、KeyGeneratorUtils.java
      • 1.5、DefaultAuthorizationServer.java
      • 1.6、application.yml
    • 2、client项目
      • 2.1、SecurityConfig.java
      • 2.2、WebClientConfig.java
      • 2.3、AuthorizationController.java
      • 2.4、DefaultController.java
      • 2.5、Client1Application.java
      • 2.6、templates/index.html
      • 2.7、application.yml
    • 3、resource项目
      • 3.1、ResourceServerConfig.java
      • 3.2、MessagesController.java
      • 3.3、MessageResourceApplication.java
      • 3.4、application.yml

开始

spring security oauth已停更 spring security oauth migration guide ,新授权项目已迁移至spring authorization server,spring authorization server发展不容易,终于到了稍微稳当的版本。本文主要以源代码当中的示例为主,因源代码版本之间差异较大,部分示例代码会稍微改动。

演示代码请移步

spring authorization server default 示例代码

在这里插入图片描述

1、default-authorizationserver项目

在这里插入图片描述

1.1、AuthorizationServerConfig.java

@Configuration(proxyBeanMethods = false)
public class AuthorizationServerConfig {@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0// @formatter:offhttp.exceptionHandling(exceptions ->exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))).oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);// @formatter:onreturn http.build();}// @formatter:off@Beanpublic RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()).clientId("messaging-client").clientSecret("{noop}secret").clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC).authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN).authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS).redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc").redirectUri("http://127.0.0.1:8080/authorized").scope(OidcScopes.OPENID).scope(OidcScopes.PROFILE).scope("message.read").scope("message.write").clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()).build();// Save registered client in db as if in-memoryJdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);registeredClientRepository.save(registeredClient);return registeredClientRepository;}// @formatter:on@Beanpublic OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);}@Beanpublic OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);}@Beanpublic JWKSource<SecurityContext> jwkSource() {RSAKey rsaKey = Jwks.generateRsa();JWKSet jwkSet = new JWKSet(rsaKey);return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);}@Beanpublic JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);}@Beanpublic ProviderSettings authorizationServerSettings() {return ProviderSettings.builder().issuer("http://localhost:9000").build();}//	@Bean
//	public EmbeddedDatabase embeddedDatabase() {
//		// @formatter:off
//		return new EmbeddedDatabaseBuilder()
//				.generateUniqueName(true)
//				.setType(EmbeddedDatabaseType.H2)
//				.setScriptEncoding("UTF-8")
//				.addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-schema.sql")
//				.addScript("org/springframework/security/oauth2/server/authorization/oauth2-authorization-consent-schema.sql")
//				.addScript("org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql")
//				.build();
//		// @formatter:on
//	}}

1.2、DefaultSecurityConfig.java

@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class DefaultSecurityConfig {// @formatter:off@BeanSecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize ->authorize.anyRequest().authenticated()).formLogin(withDefaults());return http.build();}// @formatter:on// @formatter:off@BeanUserDetailsService users() {UserDetails user = User.withDefaultPasswordEncoder().username("user1").password("password").roles("USER").build();return new InMemoryUserDetailsManager(user);}// @formatter:on}

1.3、Jwks.java

public final class Jwks {private Jwks() {}public static RSAKey generateRsa() {KeyPair keyPair = KeyGeneratorUtils.generateRsaKey();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();// @formatter:offreturn new RSAKey.Builder(publicKey).privateKey(privateKey).keyID(UUID.randomUUID().toString()).build();// @formatter:on}public static ECKey generateEc() {KeyPair keyPair = KeyGeneratorUtils.generateEcKey();ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();Curve curve = Curve.forECParameterSpec(publicKey.getParams());// @formatter:offreturn new ECKey.Builder(curve, publicKey).privateKey(privateKey).keyID(UUID.randomUUID().toString()).build();// @formatter:on}public static OctetSequenceKey generateSecret() {SecretKey secretKey = KeyGeneratorUtils.generateSecretKey();// @formatter:offreturn new OctetSequenceKey.Builder(secretKey).keyID(UUID.randomUUID().toString()).build();// @formatter:on}
}

1.4、KeyGeneratorUtils.java

final class KeyGeneratorUtils {private KeyGeneratorUtils() {}static SecretKey generateSecretKey() {SecretKey hmacKey;try {hmacKey = KeyGenerator.getInstance("HmacSha256").generateKey();} catch (Exception ex) {throw new IllegalStateException(ex);}return hmacKey;}static KeyPair generateRsaKey() {KeyPair keyPair;try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);keyPair = keyPairGenerator.generateKeyPair();} catch (Exception ex) {throw new IllegalStateException(ex);}return keyPair;}static KeyPair generateEcKey() {EllipticCurve ellipticCurve = new EllipticCurve(new ECFieldFp(new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951")),new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853948"),new BigInteger("41058363725152142129326129780047268409114441015993725554835256314039467401291"));ECPoint ecPoint = new ECPoint(new BigInteger("48439561293906451759052585252797914202762949526041747995844080717082404635286"),new BigInteger("36134250956749795798585127919587881956611106672985015071877198253568414405109"));ECParameterSpec ecParameterSpec = new ECParameterSpec(ellipticCurve,ecPoint,new BigInteger("115792089210356248762697446949407573529996955224135760342422259061068512044369"),1);KeyPair keyPair;try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");keyPairGenerator.initialize(ecParameterSpec);keyPair = keyPairGenerator.generateKeyPair();} catch (Exception ex) {throw new IllegalStateException(ex);}return keyPair;}
}

1.5、DefaultAuthorizationServer.java

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

1.6、application.yml

server:port: 9000spring:devtools:restart:enabled: truelivereload:enabled: truedatasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: 数据库用户名password: 数据库密码url: jdbc:mysql://localhost:3306/数据库名称?serverTimezone=GMT%2B8&amp&useSSL=falselogging:level:root: INFOorg.springframework.web: INFOorg.springframework.security: INFOorg.springframework.security.oauth2: INFO
#    org.springframework.boot.autoconfigure: DEBUG

2、client项目

在这里插入图片描述

2.1、SecurityConfig.java

@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class SecurityConfig {@BeanWebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().requestMatchers("/webjars/**");}// @formatter:off@BeanSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize ->authorize.anyRequest().authenticated()).oauth2Login(oauth2Login ->oauth2Login.loginPage("/oauth2/authorization/messaging-client-oidc").defaultSuccessUrl("/", true)).oauth2Client(withDefaults());return http.build();}// @formatter:on}

2.2、WebClientConfig.java

@Configuration
public class WebClientConfig {@BeanWebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);return WebClient.builder().apply(oauth2Client.oauth2Configuration()).build();}@BeanOAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,OAuth2AuthorizedClientRepository authorizedClientRepository) {OAuth2AuthorizedClientProvider authorizedClientProvider =OAuth2AuthorizedClientProviderBuilder.builder().authorizationCode().refreshToken().clientCredentials().build();DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);return authorizedClientManager;}
}

2.3、AuthorizationController.java

@Controller
public class AuthorizationController {private final WebClient webClient;private final String messagesBaseUri;public AuthorizationController(WebClient webClient,@Value("${messages.base-uri}") String messagesBaseUri) {this.webClient = webClient;this.messagesBaseUri = messagesBaseUri;}@GetMapping(value = "/authorize", params = "grant_type=authorization_code")public String authorizationCodeGrant(Model model,@RegisteredOAuth2AuthorizedClient("messaging-client-authorization-code")OAuth2AuthorizedClient authorizedClient) {String[] messages = this.webClient.get().uri(this.messagesBaseUri).attributes(oauth2AuthorizedClient(authorizedClient)).retrieve().bodyToMono(String[].class).block();model.addAttribute("messages", messages);return "index";}// '/authorized' is the registered 'redirect_uri' for authorization_code@GetMapping(value = "/authorized", params = OAuth2ParameterNames.ERROR)public String authorizationFailed(Model model, HttpServletRequest request) {String errorCode = request.getParameter(OAuth2ParameterNames.ERROR);if (StringUtils.hasText(errorCode)) {model.addAttribute("error",new OAuth2Error(errorCode,request.getParameter(OAuth2ParameterNames.ERROR_DESCRIPTION),request.getParameter(OAuth2ParameterNames.ERROR_URI)));}return "index";}@GetMapping(value = "/authorize", params = "grant_type=client_credentials")public String clientCredentialsGrant(Model model) {String[] messages = this.webClient.get().uri(this.messagesBaseUri).attributes(clientRegistrationId("messaging-client-client-credentials")).retrieve().bodyToMono(String[].class).block();model.addAttribute("messages", messages);return "index";}
}

2.4、DefaultController.java

@Controller
public class DefaultController {@GetMapping("/")public String root() {return "redirect:/index";}@GetMapping("/index")public String index() {return "index";}@ResponseBody@GetMapping("/code")public String code(String code) {return code;}
}

2.5、Client1Application.java

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

2.6、templates/index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5"><head><title>Spring Security OAuth 2.0 Sample</title><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.css" th:href="@{/webjars/bootstrap/css/bootstrap.css}" /></head><body><div th:fragment="header"><nav class="navbar navbar-default"><div class="container"><div class="container-fluid"><div class="navbar-collapse collapse" id="navbar"></div></div></div></nav></div><div class="container"><div th:if="${error}" class="alert alert-danger alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button><h4 th:text="${error}" class="text-center"></h4></div><div class="panel panel-default"><div class="panel-heading"><h3 class="panel-title">Authorize the client using <span style="font-family:monospace">grant_type</span>:</h3></div><ul class="list-group"><li class="list-group-item"><a href="/authorize?grant_type=authorization_code" th:href="@{/authorize?grant_type=authorization_code}"><span style="font-size:medium">Authorization Code</span>&nbsp;&nbsp;<small class="text-muted">(Login to Spring Authorization Server using: user1/password)</small></a></li><li class="list-group-item"><a href="/authorize?grant_type=client_credentials" th:href="@{/authorize?grant_type=client_credentials}"><span style="font-size:medium">Client Credentials</span></a></li></ul><div th:if="${messages}" class="panel-footer"><h4>Messages:</h4><table class="table table-condensed"><tbody><tr class="row" th:each="message : ${messages}"><td th:text="${message}">message</td></tr></tbody></table></div></div></div><script src="/webjars/jquery/jquery.min.js" th:src="@{/webjars/jquery/jquery.min.js}"></script><script src="/webjars/bootstrap/js/bootstrap.min.js" th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script></body>
</html>

2.7、application.yml

server:port: 8080logging:level:root: INFOorg.springframework.web: INFOorg.springframework.security: INFOorg.springframework.security.oauth2: INFO
#    org.springframework.boot.autoconfigure: DEBUGspring:thymeleaf:cache: falsesecurity:oauth2:client:registration:messaging-client-oidc:provider: springclient-id: messaging-clientclient-secret: secretauthorization-grant-type: authorization_coderedirect-uri: "http://127.0.0.1:8080/login/oauth2/code/{registrationId}"scope: openid, profileclient-name: messaging-client-oidcmessaging-client-authorization-code:provider: springclient-id: messaging-clientclient-secret: secretauthorization-grant-type: authorization_coderedirect-uri: "http://127.0.0.1:8080/authorized"scope: message.read,message.writeclient-name: messaging-client-authorization-codemessaging-client-client-credentials:provider: springclient-id: messaging-clientclient-secret: secretauthorization-grant-type: client_credentialsscope: message.read,message.writeclient-name: messaging-client-client-credentialsprovider:spring:issuer-uri: http://localhost:9000messages:base-uri: http://127.0.0.1:8090/messages

3、resource项目

在这里插入图片描述

3.1、ResourceServerConfig.java

@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class ResourceServerConfig {// @formatter:off@BeanSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.csrf().disable().cors().disable().securityMatcher("/messages/**", "/user/**").authorizeHttpRequests().anyRequest().authenticated().and()
//				.authorizeHttpRequests()
//					.requestMatchers("/messages/**").hasAuthority("SCOPE_message.read")
//					.and().oauth2ResourceServer().jwt();return http.build();}// @formatter:on}

3.2、MessagesController.java

@RestController
public class MessagesController {@GetMapping("/messages")public String[] getMessages() {return new String[] {"Message 1", "Message 2", "Message 3"};}@GetMapping("/user")public Jwt user() {Jwt principal = (Jwt) SecurityContextHolder.getContext().getAuthentication().getPrincipal();System.out.println(principal);// 查询数据库获取用户信息return principal;}
}

3.3、MessageResourceApplication.java

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

3.4、application.yml

server:port: 8090logging:level:root: INFOorg.springframework.web: INFOorg.springframework.security: INFOorg.springframework.security.oauth2: INFO
#    org.springframework.boot.autoconfigure: DEBUGspring:security:oauth2:resourceserver:jwt:issuer-uri: http://localhost:9000

http://chatgpt.dhexx.cn/article/5VIeHP5U.shtml

相关文章

Authorization Server 认证服务

Hi Auth HiAuth是一个开源的基于Oauth2协议的认证、授权系统&#xff0c;除了标准的Oauth2授权流程功能外&#xff0c;还提供了应用管理、用户管理、权限管理等相关功能。 在这个项目中你能够了解到如何基于spring-security-oauth2-authorization-server实现自己的Authorizat…

java authorization_OkHttp3 之 Authorization处理认证(四)

处理验证 这部分和HTTP AUTH有关. HTTP AUTH 使用HTTP AUTH需要在server端配置http auth信息, 其过程如下:客户端发送http请求 服务器发现配置了http auth, 于是检查request里面有没有”Authorization”的http header 如果有, 则判断Authorization里面的内容是否在用户列表里面…

shiro授权过程

一、授权的核心概念 授权&#xff0c;也就是权限认证或访问控制&#xff0c;即在应用中控制谁能访问哪些资源 授权中的核心要素&#xff1a; 1 用户&#xff0c;在shiro中代表访问系统的任何客户端&#xff0c;即subject 2 角色&#xff0c;是权限的集合&#xff0c;或字符串值…

安全-认证授权、数据脱敏

一、认证授权 JWT &#xff1a;JWT&#xff08;JSON Web Token&#xff09;是一种身份认证的方式&#xff0c;JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的&#xff0c;因此接收者便可以验证它的真实性。 SSO(单点登录) &#xff1a;SSO(Single Sign On) 即单…

认证 (authentication) 和授权 (authorization) 的区别

以前一直傻傻分不清各种网际应用中 authentication 和 authorization, 其实很简单: 这两个术语通常在安全性方面相互结合使用&#xff0c;尤其是在获得对系统的访问权限时。两者都是非常重要的主题&#xff0c;通常与网络相关联&#xff0c;作为其服务基础架构的关键部分。然而…

Authorization—权限控制流程

本篇是对Shiro体系架构的介绍&#xff0c;本栏目大部分内容来自于Shiro官网。翻译过程中已经尽量保证用词的准确性和易懂性&#xff0c;如有不准确或者不确切的地方&#xff0c;请联系作者加以修改。本篇内容翻译自Authorization特征与Authorization官方指南。 Authorization&…

认证 (Authentication) 和授权 (Authorization)的区别是什么?

说简单点就是&#xff1a; 认证 (Authentication)&#xff1a; 你是谁。 授权 (Authorization)&#xff1a; 你有哪些权限 干什么事情。 稍微正式点&#xff08;啰嗦点&#xff09;的说法就是&#xff1a; Authentication&#xff08;认证&#xff09; 是验证您的身份的凭据&a…

变量定义与类型

命名 保留字与关键字 关键字是系统已经用的&#xff0c;保留字是系统自带的的保留 为以后使用做准备 查看关键字方法 import keyword #引入关键字模块 print &#xff08;keyword.kwlist&#xff09; #打印系统全部关键字 变量声明 三种格 #格式1 s1 &#xff02;北京图灵学…

Java变量定义时候的注意事项

常量定义的基本注意事项 在JAVA语言中&#xff0c;主要利用final关键字&#xff0c;&#xff08;在java类中灵活使用Static关键字&#xff09;来定义常量。 当常量被设定后&#xff0c;一般情况下就不允许在进行修改&#xff0c;如可以利用以下形式来定义一个常量:final doubl…

变量的定义和使用

目录 一、变量的定义 二、变量的组成 1.标识 2.类型 3.值 三、变量的多次赋值 一、变量的定义 变量名(name) 赋值运算符() 值(小王) name 小王 二、变量的组成 1.标识 表示对象所存储的物理地址&#xff0c;使用内置函数 id(obj) 来获取。 print(id(name)) 运行…

C语言中变量声明和变量定义的区别

本文转载至CSDN博客JeanCheng 变量声明和变量定义 变量定义&#xff1a;用于为变量分配存储空间&#xff0c;还可为变量指定初始值。程序中&#xff0c;变量有且仅有一个定义。变量声明&#xff1a;用于向程序表明变量的类型和名字。定义也是声明&#xff0c;extern声明不是定义…

C++ 中的变量定义

变量定义就是告诉编译器在何处创建变量的存储&#xff0c;以及如何创建变量的存储。 变量定义指定一个数据类型&#xff0c;并包含了该类型的一个或多个变量的列表&#xff0c;如下所示&#xff1a; type variable_list; 在这里&#xff0c;type 必须是一个有效的 C 数据类型…

十:变量的定义和声明的区别?

1. 变量的声明&#xff1a; 声明是用来告诉编译器变量的名称和类型&#xff0c;而不分配内存。变量的声明有两重含义&#xff1a; 告诉编译器&#xff0c;这个名字已经匹配到一块内存上&#xff0c;下面的代码用到变量或者对象是在别的地方定义的。声明可以出现多次。 告诉编译…

C语言基础教程 之 如何定义变量!

变量定义就是告诉编译器在何处创建变量的存储&#xff0c;以及如何创建变量的存储。变量定义指定一个数据类型&#xff0c;并包含了该类型的一个或多个变量的列表&#xff0c;如下所示&#xff1a; type variable_list; 在这里&#xff0c;type 必须是一个有效的 C 数据类型&…

变量的定义

变量 变量用于存储编程所使用的数据和方法。 声明一般变量的关键字&#xff1a;var,let,const.其中let和const是es6的语法。 声明其他特殊变量的关键字&#xff1a;function,class,improt&#xff08;先了解&#xff09;等 声明变量 变量用于存储数据,因此可以把变量实际上就…

03-变量的定义

一、变量的定义 1.变量是什么&#xff1f; 一句话概括&#xff1a;变量是用来临时保存数据的&#xff0c;该数据是可以变化的数据。 2.什么时候需要定义变量&#xff1f; 如果某个内容需要多次使用&#xff0c;并且在代码中重复出现&#xff0c;那么可以用变量代表该内容。…

【论文阅读】ICRA2021: VDB-EDT An Efficient Euclidean Distance Transform Algorithm Based on VDB Data Struct

参考与前言 Summary: 浩哥推荐的一篇 无人机下的建图 and planning实验 Type: ICRA Year: 2021 论文链接&#xff1a;https://arxiv.org/abs/2105.04419 youtube presentation video&#xff1a;https://youtu.be/Bojh6ylYUOo 代码链接&#xff1a;https://github.com/zhud…

scipy.ndimage.distance_transform_edt 和 cv2.distanceTransform用法

scipy.ndimage.distance_transform_edt 和 cv2.distanceTransform 的作用都是计算一张图上每个前景像素点到背景的最近距离。 import cv2 import numpy as np from scipy.ndimage import distance_transform_edta np.array(([0, 1, 1, 1, 1],[0, 0, 1, 1, 1],[0, 1, 1, 1, 1]…