Spring Security Oauth2.1 最新版 1.1.0 整合 gateway 完成授权认证(拥抱 springboot 3.1)

news2024/12/23 18:53:49

目录

背景

版本

Spring Boot 3.1

Spring Authorization Server 1.1.0官方文档

基础

spring security

OAuth2.0

模块构成

授权方式

集成过程

官方demo

代码集成

依赖

授权服务AuthorizationServerConfig配置

重要组件

测试

查看授权服务配置

访问授权服务

授权

回调

获取 access_token

个性化改造

集成GateWay

代办事项 

sql脚本


背景

基于 Spring Cloud Alibaba  架构下,需要一个统一授权中心,与 gateway 配合使用实现微服务的授权与认证,下面主要介绍整个集成过程,基于springboot3.1最新版

版本

Spring Boot 3.1

最新发布的springboot3.1版本对 oauth2 提供了默认的支持,可以引用下面的依赖来快速构建,为了体验新版本特性,我这边切换到了 3.1版本

Spring Boot 3.1 提供了一个 spring-boot-starter-oauth2-authorization-server 启动器,可以支持 Spring Authorization Server 的自动配置,轻松配置基于 Servlet 的 OAuth2 授权服务器,同时@EnableAuthorizationServer这些注解也早已废弃

Spring Authorization Server 1.1.0官方文档

Spring Authorization Server

基础

spring security

关于springsecurity的基础知识,之前写过一篇 springboot 与 Spring Security 集成的基于 jwt的授权的,可以看下面的

(296条消息) springboot 2.7整合spring security 5.7整合jwt实现用户登录注册与鉴权全记录_ricardo.M.Yu的博客-CSDN博客

OAuth2.0

 OAuth2.0可以提供一个统一的认证服务。主要模块如下:

模块构成

  • Resource owner(资源拥有者):拥有该资源的服务或用户,如我们自己或者资源网站
  • Authorization server(认证服务器):即用来认证与颁发令牌(如token)的服务
  • Resource server(资源服务器):拥有资源的服务,如我们要访问的网站
  • Client(客户端):即访问的客户端,如我们自己用的访问网站

授权方式

  • 授权码模式(authorization_code):最正规的模式,客户端先将用户导向认证服务器,登录后获取授权码,然后进行授权,最后根据授权码获取访问令牌
  • 刷新模式(refresh_token):用刷新码获取
  • 客户端模式(client_credentials):第三方应用自己本身需要获取资源

详见  AuthorizationGrantType 这个类

下面的密码模式已经被废弃

  • 密码模式(resource owner password credentials):直接带用户名和密码去向认证服务器申请令牌

集成过程

我下面会分为三个阶段逐次递进改造,

  • 第一阶段:官方demo演示与组件讲解测试
  • 第二阶段:个性化改造
  • 第三阶段:集成 springcloud gateway 完成分布式授权改造

官方demo

代码集成

依赖

只需要下面的这一个依赖,前提springboot 版本为 3.1

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.0</version>
    <relativePath/>
</parent>


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>

授权服务AuthorizationServerConfig配置

spring 官方在快速开始里面给出了下面的默认最小配置,

Getting Started (spring.io)

我先粘下来再介绍,代码结构大概这样,一共两个配置类

 AuthorizationServerConfig


@Configuration
public class AuthorizationServerConfig {

    @Bean
    @Order(1)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
            throws Exception {
        //针对 Spring Authorization Server 最佳实践配置
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
                .oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0

        http
                // 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((resourceServer) -> resourceServer
                        .jwt(Customizer.withDefaults()));

        return http.build();
    }

    @Bean
    public RegisteredClientRepository registeredClientRepository() {
        RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString())
                .clientId("oidc-client")
                .clientSecret("{noop}secret")
                .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                .redirectUri("http://www.baidu.com")
                .redirectUri("http://127.0.0.1:8080/login/oauth2/code/oidc-client")
                .postLogoutRedirectUri("http://127.0.0.1:8080/")
                .scope(OidcScopes.OPENID)
                .scope(OidcScopes.PROFILE)
                .scope("message.read")
                .scope("message.write")
                .scope("all")
                // 设置 Client 需要页面审核授权
                .clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
                .build();

        return new InMemoryRegisteredClientRepository(oidcClient);
    }

    /**
     * 默认发放令牌
     * @return
     */
    @Bean
    public JWKSource<SecurityContext> jwkSource() {
        KeyPair keyPair = generateRsaKey();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAKey rsaKey = new RSAKey.Builder(publicKey)
                .privateKey(privateKey)
                .keyID(UUID.randomUUID().toString())
                .build();
        JWKSet jwkSet = new JWKSet(rsaKey);
        return new ImmutableJWKSet<>(jwkSet);
    }

    private 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;
    }

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

    @Bean
    public AuthorizationServerSettings authorizationServerSettings() {
        return AuthorizationServerSettings.builder().build();
    }
}

DefaultSecurityConfig

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


    @Bean
    @Order(2)
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
            throws Exception {
        http
                .authorizeHttpRequests((authorize) -> authorize
                        .requestMatchers(new AntPathRequestMatcher("/actuator/**"),
                                new AntPathRequestMatcher("/oauth2/**"),
                                new AntPathRequestMatcher("/**/*.json"),
                                new AntPathRequestMatcher("/**/*.html")).permitAll()
                        .anyRequest().authenticated()
                )
                .cors(Customizer.withDefaults())
                .csrf((csrf) -> csrf.disable())
//                .httpBasic(Customizer.withDefaults())
//				// Form login handles the redirect to the login page from the
//				// authorization server filter chain
                .formLogin(Customizer.withDefaults())
        ;

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails userDetails = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(userDetails);
    }

}

分别介绍下这几个@Bean配置,也是 AuthorizationServer 的几个重要概念。

重要组件

  • SecurityFilterChain -> authorizationServerSecurityFilterChain: Spring Security的过滤器链,用于协议端点的。

  • SecurityFilterChain -> defaultSecurityFilterChain: Spring Security的过滤器链,用于Spring Security的身份认证

  • UserDetailsService :主要进行用户身份验证

  • RegisteredClientRepository:主要用于管理客户端

  • JWKSource:用于签名访问令牌

  • KeyPair: 启动时生成的带有密钥的KeyPair实例,用于创建上面的JWKSource

  • JwtDecoder:JwtDecoder的一个实例,用于解码已签名的访问令牌

  • AuthorizationServerSettings:用于配置Spring Authorization Server的AuthorizationServerSettings实例。

测试

为了方便测试,上面的配置中,客户端的回调地址我已经改成了 百度的,授权方式用授权码模式,认证方式用client_secret_basic

服务启动,端口为9000

查看授权服务配置

地址:

调用  http://127.0.0.1:9000/.well-known/openid-configuration

 后,查看地址配置如下:其实就是每个请求的url

详细的是下面

{

    "issuer": "http://127.0.0.1:9000",

    "authorization_endpoint": "http://127.0.0.1:9000/oauth2/authorize",

    "device_authorization_endpoint": "http://127.0.0.1:9000/oauth2/device_authorization",

    "token_endpoint": "http://127.0.0.1:9000/oauth2/token",

    "token_endpoint_auth_methods_supported": [

        "client_secret_basic",

        "client_secret_post",

        "client_secret_jwt",

        "private_key_jwt"

    ],

    "jwks_uri": "http://127.0.0.1:9000/oauth2/jwks",

    "userinfo_endpoint": "http://127.0.0.1:9000/userinfo",

    "end_session_endpoint": "http://127.0.0.1:9000/connect/logout",

    "response_types_supported": [

        "code"

    ],

    "grant_types_supported": [

        "authorization_code",

        "client_credentials",

        "refresh_token",

        "urn:ietf:params:oauth:grant-type:device_code"

    ],

    "revocation_endpoint": "http://127.0.0.1:9000/oauth2/revoke",

    "revocation_endpoint_auth_methods_supported": [

        "client_secret_basic",

        "client_secret_post",

        "client_secret_jwt",

        "private_key_jwt"

    ],

    "introspection_endpoint": "http://127.0.0.1:9000/oauth2/introspect",

    "introspection_endpoint_auth_methods_supported": [

        "client_secret_basic",

        "client_secret_post",

        "client_secret_jwt",

        "private_key_jwt"

    ],

    "subject_types_supported": [

        "public"

    ],

    "id_token_signing_alg_values_supported": [

        "RS256"

    ],

    "scopes_supported": [

        "openid"

    ]

}

访问授权服务

浏览器地址栏输入

http://localhost:9000/oauth2/authorize?response_type=code&client_id=oidc-client&scope=message.read&redirect_uri=http://www.baidu.com

用这个请求来模拟客户端,实际开发中,其实是先访问资源服务,由资源服务来拼接这几个参数来重定向到授权服务的,参数意义如下,这些参数都是需要再上面RegisteredClientRepository配置过的

  • response_type:这个意思是相应的方式为code码
  • client_id:即客户端的id,即上面配置中在 RegisteredClientRepository 配置的
  • scope:请求授权范围,也需要在上面的配置中
  • redirect_uri:授权通过后,重定向回来的地址

输入完上面的地址后,会重定向到下面这个登录页面,

我们输入上面配置好的用户名密码:

user

password

点击登录 

授权

登录过后,会到下面这个授权页面,点击授权范围,然后点击 submit

回调

授权通过后,授权服务回调到了百度的地址,然后附带这我们的授权码,如下图

获取 access_token

拿到授权码之后,可以用postman测试来获取 access_token

测试接口参数

Header

请求体 

http://localhost:9000/oauth2/token?grant_type=authorization_code&code=ajdNNIj8EiLjgw3OS8yu2q8n3XXCAb6cPY5LRsOHyRlAAB1ENKdmy8M4JBkJ8PrU-3K9QdpAZtyKg8QP5q0EHN2mR1k532FQUKz1ObSuH3EuSFy5LVzut9z1QVPuefoA&redirect_uri=http://www.baidu.com

curl命令如下

curl --location --request POST 'http://localhost:9000/oauth2/token?grant_type=authorization_code&code=a_lOQegEwElR09Sj6auVpBdYGgnhhK0uz1Uks286ei_zkbyDFKII2uf7gMIF7CU4cLN8ZEY3EsSq9jMAZ-Rmtmlq5pI6KPB95LMQg9fFirFg2wWjdd5PEwQLMEogY9B6&redirect_uri=http%3A%2F%2Fwww.baidu.com' \
--header 'Authorization: Basic b2lkYy1jbGllbnQ6c2VjcmV0'

 参数说明:

  • grant_type:即授权方式,authorization_code即授权码模式
  • code:即授权码,上面重定向到百度给我们的授权码
  • redirect_uri:重定向的url

  • header中的 Authorization参数:因为我们用的客户端认证方式 为  client_secret_basic ,这个需要传参,还有一些其他的认证方式,具体参数说明如下
  • client_secret_basic: 将 clientId 和 clientSecret 通过 ‘:’ 号拼接,( clientId 和 clientSecret 都在上面配置中,)并使用 Base64 进行编码得到一串字符,再在前面加个 注意有个 Basic   前缀(Basic后有一个空格), 即得到上面参数中的 Basic b2lkYy1jbGllbnQ6c2VjcmV0
  • client_secret_post :clientId 和 clientSecret 放到表单去发送请求。如下图:

 使用我们的 client_secret_basic 方式传参,接口调用结果:

已经正常拿到了 access_token。

完整的过滤器执行顺序,控制台输出

 

个性化改造

正在改造中。。。

集成GateWay

正在集成中。。。

关于 Spring Cloud Alibaba 的基础环境搭建,可以看下面的文章,很详细,本文主要介绍集成OAuth2的过程

Spring Cloud Alibaba 最新版本整合完整使用及与各中间件集成(基于Spring Boot 3.0.x)_ricardo.M.Yu的博客-CSDN博客

代办事项 

现在需要做的改造如下:

1、新建授权服务,集成 oauth2-authorization-server ,即auth模块做授权中心

2、修改业务模块,集成 oauth2-client,即做资源中心与客户端

3、修改网关模块,即 gateway 做相关修改

Oauth2主要结构

OAuth2AuthorizationEndpointFilter: 针对 /login 或自行请求 授权码的处理器

OAuth2TokenEndpointFilter:针对获取 token 时的处理器

ProviderManager:

OAuth2ClientAuthenticationFilter

OAuth2TokenEndpointFilter

ClientSecretAuthenticationProvider

DelegatingAuthenticationConverter

OAuth2AuthorizationCodeAuthenticationProvider

OAuth2AuthorizationEndpointFilter

UsernamePasswordAuthenticationFilter

sql脚本

我直接整理好了

/*
IMPORTANT:
    If using PostgreSQL, update ALL columns defined with 'blob' to 'text',
    as PostgreSQL does not support the 'blob' data type.
*/
CREATE TABLE oauth2_authorization (
    id varchar(100) NOT NULL,
    registered_client_id varchar(100) NOT NULL,
    principal_name varchar(200) NOT NULL,
    authorization_grant_type varchar(100) NOT NULL,
    authorized_scopes varchar(1000) DEFAULT NULL,
    attributes blob DEFAULT NULL,
    state varchar(500) DEFAULT NULL,
    authorization_code_value blob DEFAULT NULL,
    authorization_code_issued_at timestamp DEFAULT NULL,
    authorization_code_expires_at timestamp DEFAULT NULL,
    authorization_code_metadata blob DEFAULT NULL,
    access_token_value blob DEFAULT NULL,
    access_token_issued_at timestamp DEFAULT NULL,
    access_token_expires_at timestamp DEFAULT NULL,
    access_token_metadata blob DEFAULT NULL,
    access_token_type varchar(100) DEFAULT NULL,
    access_token_scopes varchar(1000) DEFAULT NULL,
    oidc_id_token_value blob DEFAULT NULL,
    oidc_id_token_issued_at timestamp DEFAULT NULL,
    oidc_id_token_expires_at timestamp DEFAULT NULL,
    oidc_id_token_metadata blob DEFAULT NULL,
    refresh_token_value blob DEFAULT NULL,
    refresh_token_issued_at timestamp DEFAULT NULL,
    refresh_token_expires_at timestamp DEFAULT NULL,
    refresh_token_metadata blob DEFAULT NULL,
    user_code_value blob DEFAULT NULL,
    user_code_issued_at timestamp DEFAULT NULL,
    user_code_expires_at timestamp DEFAULT NULL,
    user_code_metadata blob DEFAULT NULL,
    device_code_value blob DEFAULT NULL,
    device_code_issued_at timestamp DEFAULT NULL,
    device_code_expires_at timestamp DEFAULT NULL,
    device_code_metadata blob DEFAULT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE oauth2_authorization_consent (
    registered_client_id varchar(100) NOT NULL,
    principal_name varchar(200) NOT NULL,
    authorities varchar(1000) NOT NULL,
    PRIMARY KEY (registered_client_id, principal_name)
);

CREATE TABLE oauth2_registered_client (
    id varchar(100) NOT NULL,
    client_id varchar(100) NOT NULL,
    client_id_issued_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
    client_secret varchar(200) DEFAULT NULL,
    client_secret_expires_at timestamp DEFAULT NULL,
    client_name varchar(200) NOT NULL,
    client_authentication_methods varchar(1000) NOT NULL,
    authorization_grant_types varchar(1000) NOT NULL,
    redirect_uris varchar(1000) DEFAULT NULL,
    post_logout_redirect_uris varchar(1000) DEFAULT NULL,
    scopes varchar(1000) NOT NULL,
    client_settings varchar(2000) NOT NULL,
    token_settings varchar(2000) NOT NULL,
    PRIMARY KEY (id)
);


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

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

相关文章

AB32VG1:SDK_AB53XX_V061(5)蓝牙BLE测试笔记

文章目录 1.配置工程&#xff0c;重新编译1.1替换链接库libbtstack_dm.a1.2 《config.h》打开编译开关1.3 在 Downloader 里面打开 BLE 开关 2.ABLink&#xff08;手机APP&#xff09;控制2.1 app下载2.2 安装后打开&#xff0c;搜索蓝牙Bluetrum&#xff1a;2.3 操作存储卡 3.…

深度学习应用篇-元学习[14]:基于优化的元学习-MAML模型、LEO模型、Reptile模型

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

华为认证 | HCIP-Datacom-Core 考试大纲

01 考试概况 02 考试内容 HCIP-Datacom-Core Technology V1.0考试覆盖数据通信领域各场景通用核心知识&#xff0c;包括路由基础、OSPF、 IS-IS、BGP、路由和流量控制、以太网交换技术、组播、IPv6、网络安全、网络可靠性、网络服务与管理、 WLAN、网络解决方案。 ★路由基础 …

【MySQL 函数】:一文彻底搞懂 MySQL 函数(一)

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL字符串函数和数学函数的讲解✨ 目录 前言一、字符串函数二、数学函数三、总结 一、字符串函数 函数作用UPPER(列|字符串)将字符串每个字符转为大写LOWER(列|字符串)将字符串每个字符转为小写CONCAT(str1,str2,…

阿里云企业邮箱购买流程

阿里云企业邮箱购买流程&#xff0c;企业邮箱分为免费版、标准版、集团版和尊享版&#xff0c;阿里云百科分享企业邮箱版本区别&#xff0c;企业邮箱收费标准价格表&#xff0c;以及阿里企业邮箱详细购买流程&#xff1a; 目录 阿里云企业邮箱购买流程 一、阿里云账号注册及…

OpenAI 刚刚宣布了海量更新

OpenAI 刚刚宣布了海量更新&#xff0c;增加函数调用&#xff0c;支持更长上下文&#xff0c;价格更低&#xff01; ​新模型上架 1、gpt-4-0613 2、gpt-4-32k-0613 3、gpt-3.5-turbo-0613 4、gpt-3.5-turbo-16k 部分模型降价 1、text-embedding-ada-002&#xff1a;$0.00…

DevExpress WinForms功能区组件,让业务应用创建更轻松!(上)

DevExpress WinForms的Ribbon&#xff08;功能区&#xff09;组件灵感来自于Microsoft Office&#xff0c;并针对WinForms开发人员进行了优化&#xff0c;它可以帮助开发者轻松地模拟当今最流行的商业生产应用程序。 PS&#xff1a;DevExpress WinForm拥有180组件和UI库&#…

Linux安装SQLServer数据库

Linux安装SQLServer数据库 文章目录 Linux安装SQLServer数据库SQLServer是什么SQLServer的安装安装要求安装步骤安装配置安装命令行工具 SQLServer是什么 美国 Microsoft 公司推出的一种关系型数据库系统。SQL Server 是一个可扩展的、高性能的、为分布式客户机/服务器计算所设…

[PostgreSQL-16新特性之EXPLAIN的GENERIC_PLAN选项]

随着PostgreSQL-16beta1版本的发布&#xff0c;我们可以发现&#xff0c;对于我们时常使用的explain增加了一个GENERIC_PLAN选项。这个选项是允许了包含参数占位符的语句&#xff0c;如select * from tab01 where id$1;等等这种语句&#xff0c;让其生成不依赖于这些参数值的通…

两个HC-05蓝牙之间的配对

两个HC-05蓝牙之间的配对 文章目录 两个HC-05蓝牙之间的配对1.进入AT指令模式后&#xff0c;先确定是否为AT模式&#xff1a;2.获取模块A,B的地址3.将蓝牙A配置为主模式&#xff0c;将蓝牙B配置为从模式&#xff1a;4.设置模块通信波特率,蓝牙模块A和B的配置需要相同6.验证 买了…

目标检测数据集---玻璃瓶盖工业缺陷数据集

✨✨✨✨✨✨目标检测数据集✨✨✨✨✨✨ 本专栏提供各种场景的数据集,主要聚焦:工业缺陷检测数据集、小目标数据集、遥感数据集、红外小目标数据集,该专栏的数据集会在多个专栏进行验证,在多个数据集进行验证mAP涨点明显,尤其是小目标、遮挡物精度提升明显的数据集会在该…

儿童遗留监测成为「加分项」,多种技术路线「争夺战」一触即发

儿童遗留密闭车内&#xff0c;温度可以在短短15分钟内达到临界水平&#xff0c;从而可能导致中暑和死亡&#xff0c;尤其是当汽车在太阳底下暴晒。 按照Euro NCAP给出的指引&#xff0c;与车祸相比&#xff0c;儿童因车辆中暑而死亡的情况较少&#xff0c;但却是完全可以避免的…

计算机网络开荒4-网络层

文章目录 一、网络层概述1.1 路由转发1.2 建立连接1.3 网络服务类型 二、虚拟电路与数据报网络2.1 虚电路Virtual circuits VC网络2.1.1 VC 实现2.1.1 虚电路信令协议(signaling protocols) 2.2 数据报网络2.3 对比 三、Internet网络的网络层 IP协议3.1 IP分片3.1.1 最大传输单…

中创|数据中心集聚,算力企业环绕,郑州:力争打造中部最强数据中心集群

信息时代&#xff0c;算力就是生产力。从田间到车间、从陆地到天空&#xff0c;算力的应用已经在方方面面“大显身手”。不仅是在存储领域&#xff0c;在具体的应用服务领域&#xff0c;算力也无处不在。 手机支付、网上购物、精准导航、人脸识别……这些人们熟悉的生活场景&a…

如何在telnet连接的情况下下载上传文件

1.下载tftp文件 TFTP下载-TFTP正式版下载[电脑版]-华军软件园 2.选择自己PC机所在的IP 3.telnet登录到设备 4.上传下载 //上传&#xff1a; 从Clinet&#xff08;设备&#xff09;上传文件到Server&#xff08;PC机&#xff09;时&#xff0c; 使用下面的命令 tftp –p –…

cesium学习笔记

cesium入门笔记 一、下载源码&#xff0c;源码介绍二、html案例体验三、cesium中的类介绍1.它们分别是&#xff1a;2.四大类的完整演示代码&#xff1a; 四、cesium的坐标与转换五、相机系统介绍六、地图、地形的加载七、建筑体添加和使用八、空间数据加载1、加载数据2、对加载…

python中变量与字符串详解!!

❄️作者介绍&#xff1a;奇妙的大歪❄️ &#x1f380;个人名言&#xff1a;但行前路&#xff0c;不负韶华&#xff01;&#x1f380; &#x1f43d;个人简介&#xff1a;云计算网络运维专业人员&#x1f43d; 前言 初学者经常会遇到的困惑是&#xff0c;看书上或者是听课都懂…

数据库:mysqldump用法详解

目录 一、命令格式详解 1.1 语法格式 1.2 常用参数 1.3 完整参数 二、mysqldump常见的几个错误 2.1、提示命令未找到 -bash: mysqldump: 未找到命令 2.2、 the command line interface can be insecure 2.3、Gotpacket bigger than ‘max_allowed_packet‘ bytes 一、命令格式详…

GPT-4官方使用经验都在里面;Stability AI联合Clipdrop推出一键改变图像比例

&#x1f989; AI新闻 &#x1f680; Stability AI联合Clipdrop推出扩图工具Uncrop&#xff0c;一键改变图像比例 摘要&#xff1a;Stability AI联合Clipdrop推出的Uncrop Clipdrop是一个终极图像比例编辑器。它可以补充任何现有照片或图像&#xff0c;来更改任何图像的比例。…

apple pencil二代平替笔哪个好用?ipad平替笔合集

现在很多人都在用IPAD记录&#xff0c;或者用IPAD画图。还有就是&#xff0c;大部分的IPAD用户&#xff0c;都是以实用为主&#xff0c;他们觉得&#xff0c;要想让IPAD更加实用&#xff0c;就一定要有一款好用的电容笔。其实&#xff0c;如果只是用来做笔记&#xff0c;或者只…