spring authorization server 0.3.1 - 默认示例

news2024/12/24 22:07:26

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:off
		http
			.exceptionHandling(exceptions ->
				exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
			)
			.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
		// @formatter:on
		return http.build();
	}

	// @formatter:off
	@Bean
	public 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-memory
		JdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);
		registeredClientRepository.save(registeredClient);

		return registeredClientRepository;
	}
	// @formatter:on

	@Bean
	public OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
		return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);
	}

	@Bean
	public OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
		return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);
	}

	@Bean
	public JWKSource<SecurityContext> jwkSource() {
		RSAKey rsaKey = Jwks.generateRsa();
		JWKSet jwkSet = new JWKSet(rsaKey);
		return (jwkSelector, securityContext) -> jwkSelector.select(jwkSet);
	}

	@Bean
	public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
		return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
	}

	@Bean
	public 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
	@Bean
	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
		http
			.authorizeHttpRequests(authorize ->
				authorize.anyRequest().authenticated()
			)
			.formLogin(withDefaults());
		return http.build();
	}
	// @formatter:on

	// @formatter:off
	@Bean
	UserDetailsService 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:off
		return 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:off
		return new ECKey.Builder(curve, publicKey)
				.privateKey(privateKey)
				.keyID(UUID.randomUUID().toString())
				.build();
		// @formatter:on
	}

	public static OctetSequenceKey generateSecret() {
		SecretKey secretKey = KeyGeneratorUtils.generateSecretKey();
		// @formatter:off
		return 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: 9000

spring:
  devtools:
    restart:
      enabled: true
    livereload:
      enabled: true

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: 数据库用户名
    password: 数据库密码
    url: jdbc:mysql://localhost:3306/数据库名称?serverTimezone=GMT%2B8&amp&useSSL=false

logging:
  level:
    root: INFO
    org.springframework.web: INFO
    org.springframework.security: INFO
    org.springframework.security.oauth2: INFO
#    org.springframework.boot.autoconfigure: DEBUG

2、client项目

在这里插入图片描述

2.1、SecurityConfig.java

@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class SecurityConfig {

	@Bean
	WebSecurityCustomizer webSecurityCustomizer() {
		return (web) -> web.ignoring().requestMatchers("/webjars/**");
	}

	// @formatter:off
	@Bean
	SecurityFilterChain 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 {

	@Bean
	WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) {
		ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
				new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
		return WebClient.builder()
				.apply(oauth2Client.oauth2Configuration())
				.build();
	}

	@Bean
	OAuth2AuthorizedClientManager 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: 8080

logging:
  level:
    root: INFO
    org.springframework.web: INFO
    org.springframework.security: INFO
    org.springframework.security.oauth2: INFO
#    org.springframework.boot.autoconfigure: DEBUG

spring:
  thymeleaf:
    cache: false
  security:
    oauth2:
      client:
        registration:
          messaging-client-oidc:
            provider: spring
            client-id: messaging-client
            client-secret: secret
            authorization-grant-type: authorization_code
            redirect-uri: "http://127.0.0.1:8080/login/oauth2/code/{registrationId}"
            scope: openid, profile
            client-name: messaging-client-oidc
          messaging-client-authorization-code:
            provider: spring
            client-id: messaging-client
            client-secret: secret
            authorization-grant-type: authorization_code
            redirect-uri: "http://127.0.0.1:8080/authorized"
            scope: message.read,message.write
            client-name: messaging-client-authorization-code
          messaging-client-client-credentials:
            provider: spring
            client-id: messaging-client
            client-secret: secret
            authorization-grant-type: client_credentials
            scope: message.read,message.write
            client-name: messaging-client-client-credentials
        provider:
          spring:
            issuer-uri: http://localhost:9000

messages:
  base-uri: http://127.0.0.1:8090/messages

3、resource项目

在这里插入图片描述

3.1、ResourceServerConfig.java

@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class ResourceServerConfig {

	// @formatter:off
	@Bean
	SecurityFilterChain 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: 8090

logging:
  level:
    root: INFO
    org.springframework.web: INFO
    org.springframework.security: INFO
    org.springframework.security.oauth2: INFO
#    org.springframework.boot.autoconfigure: DEBUG

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://localhost:9000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/21073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用poi操作excel详解

使用poi操作excel详解1、POI工具介绍2、POI可操作的文件类型3、POI所需依赖4、xls和xlsx的区别5、POI Excel 写 03(xls)和07(xlsx)版本方式6、HSSF和XSSF写大文件的区别6.1、使用HSSF写大文件6.2、使用XSSF写大文件6.3、使用SXSS写大文件1、POI工具介绍 1.1、POI 是用Java编写…

为什么进程切换比线程切换代价大,效率低?【TLB:页表缓存/快表】

参考&#xff1a; 计组复习&#xff1a;cache&#xff0c;虚拟内存&#xff0c;页表与TLB小林coding - 为什么要有虚拟内存&#xff1f; 一、为什么进程切换比线程切换代价大&#xff0c;效率更低&#xff1f; 首先&#xff0c;先给出标题的答案&#xff08;关键在于进程切换…

CleanMyMac X2023最新版安装图文详解

对于刚刚入手苹果Mac设备的用户来说&#xff0c;什么软件好用、怎样设置能够获得最佳的使用体验等这些问题都需要一步一步摸索&#xff0c;但其实&#xff0c;从懵懂到熟练使用OS X系统的过程是非常有趣的。日前&#xff0c;有网友分享了自己认为在OS X系统下非常好用的软件&am…

免费查题接口系统调用

免费查题接口系统调用 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点…

Spring——Bean注入几种方式(放入容器)

Bean注入几种方式1.XML方式注入set方式注入构造方法注入2.注解方式注入ComponentComponentScanConfigurationBeanComponentScanImport3.实现ImportBeanDefinitionRegistrar接口4.实现FactoryBean5.实现BeanDefinitionRegistryPostProcessor1.XML方式注入 在现在这个Springboot…

jsp课程资源网站系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 课程资源网站系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql&#xff0c;使用…

怎么用docker将项目打包成镜像并导出给别人适用 (dockerfile)

前提 你得安装docker&#xff0c;没有安装的可以看看这篇文章 编写dockerfile 这个位置最好和我一样&#xff0c;不然后面打包成镜像可能出问题&#xff08;找不到jar包&#xff09; FROM openjdk:8-jdk-slim MAINTAINER JacksonNing COPY /target/iec104-1.0.0-SNAPSHOT.j…

这次把怎么做好一个PPT讲清-演讲篇

《商务演讲与汇报》 一、目标&#xff1a;演讲必须有清晰的目标 演讲&#xff1a;影响他人发生积极的**“改变”** 注意&#xff0c;目标就要设定的影响听众在听完你的演讲后发生积极的改变&#xff1b; 例&#xff1a;5月初向领导做月度工作汇报→→让领导在5月第一周例会…

QGradient(渐变填充)

QGradient&#xff08;渐变填充&#xff09; QGradient和QBrush一起使用来指定渐变填充。 Qt支持的填充&#xff1a; 线性渐变&#xff08;linear gradient&#xff09;,在起点和终点之间插值颜色辐射渐变&#xff08;radial gradient&#xff09;,在焦点和围绕它的圆的端点之…

2019上半年-2019下半年软件设计师上午题错题总结

2019上半年 30.以下关于极限编程&#xff08;XP&#xff09;的最佳实践的叙述中&#xff0c;不正确的是&#xff08;C &#xff09;。 A.只处理当前的需求&#xff0c;使设计保持简单 B.编写完程序之后编写测试代码 C.可以按日甚至按小时为客户提供可运行的版本 D.系统最…

【附源码】Python计算机毕业设计水库洪水预报调度系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;我…

linux进阶-构建deb软件安装包

Linux软件包的组成&#xff1a;源码包和二进制包。 文件类型保存目录普通程序/usr/binroot权限程序/usr/sbin程序配置文件/etc日志文件/var/log文档文件/usr/share/doc 源码包优点&#xff1a;开源免费、自由裁剪、修改源代码。 源码包缺点&#xff1a;安装步骤繁琐、编译时间…

【信号处理】卡尔曼滤波(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

区块链解决方案-最新全套文件

区块链解决方案-最新全套文件一、建设背景区块链的五大场景1、合同存证2、产品防伪溯源3、供应链金融4、住房租赁5、贸易金融业务二、建设架构三、建设方案四、获取 - 区块链全套最新解决方案合集一、建设背景 区块链的五大场景 1、合同存证 传统的合同存证存在着被篡改、删…

【AcWing19】【LeetCode】DFS - 46/47/39/77/216/17

文章目录代码随想录在B站的视频讲得比AcWing好模板题1&#xff1a;排列数字模板题2&#xff1a;n皇后方法一方法二LeetCode 46. 全排列LeetCode 47. 全排列 II &#xff08;重复元素&#xff09;LeetCode 39. 组合总和LeetCode 77. 组合LeetCode 216. 组合总和 IIILeetCode 17.…

黑马点评--分布式锁

黑马点评–分布式锁 基本原理与不同实现方式对比&#xff1a; 什么是分布式锁&#xff1a; ​ 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心是实现多进程之间互斥&#xff0c;而满足这一点的方式有很多&#xff0c;常见的有三种…

Leetcode799. 香槟塔

文章目录题目链接题目大意解题思路代码(C)递推递归题目链接 点我 (^_^) 题目大意 解题思路 一开始看到这个 poured 范围这么大&#xff0c;以为是可以直接推出数学公式&#xff0c;但推了半天没推出来。 然后发现&#xff0c;直接从顶部开始模拟即可&#xff0c;某个row 下的…

HIve数仓新零售项目DWB层的构建

HIve数仓新零售项目 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kaf…

October 2019 Twice SQL Injection

目录 首先&#xff0c;尝试一下回显位的个数 第二步获取数据库名称 第三步&#xff0c;获得表名 第四步&#xff0c;获得列名 最后获取flag 总结 &#xff1a;二次注入&#xff0c;首先我们需要锁定是哪里哪个文本框存在二次注入&#xff0c;以这道题为例&#xff0c;首先…

计算机视觉算法——基于Transformer的语义分割(SETR / Segmenter / SegFormer)

计算机视觉算法——基于Transformer的语义分割&#xff08;SETR / Segmenter / SegFormer&#xff09;1. SETR1.1 网络结构及特点1.1.1 Decoder1.2 实验2. Segmenter2.1 网络结构及特点2.1.1 Decoder2.2 实验3. SegFormer3.1 网络结构及特点3.1.1 Overlap Patch Merging3.1.2 E…