【Spring Security系列】10分钟实现 SpringSecurity + CAS 完美单点登录方案

 作者:后端小肥肠

🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案

🍊 有疑问可私信或评论区联系我。

🥑  创作不易未经允许严禁转载。

姊妹篇:

【Spring Security系列】如何用Spring Security集成手机验证码登录?五分钟搞定!_springsecurity短信验证码登录-CSDN博客

【Spring Security系列】基于Spring Security实现权限动态分配之菜单-角色分配及动态鉴权实践_spring secrity权限角色动态管理-CSDN博客

【Spring Security系列】基于Spring Security实现权限动态分配之用户-角色分配_spring security 角色-CSDN博客

【Spring Security系列】权限之旅:SpringSecurity小程序登录深度探索_spring security 微信小程序登录-CSDN博客

【Spring Security系列】Spring Security+JWT+Redis实现用户认证登录及登出_spring security jwt 退出登录-CSDN博客

目录

1. 前言

2. CAS单点登录原理

2.1. 核心概念

2.2. CAS单点登录流程

3. CAS Server 部署

3.1. 配置Tomcat支持HTTPS协议

3.2. CAS Server服务器搭建

3.2.1. CAS Server war下载

3.2.2. CAS Server war发布到tomcat

3.2.3. 配置数据源,数据库用户认证

3.2.4.  密码加密校验

4. SpringSecurity 整合 CAS

4.1. SpringSecurity集成CAS单点登录认证流程

4.2. 版本依赖

4.3. 核心代码

4.3.1. 后端代码

4.3.2. 前端代码

5. 结语

6. 参考链接


1. 前言

在现代分布式系统和微服务架构中,单点登录(Single Sign-On, SSO)已经成为用户身份管理中的一个重要组成部分。随着系统规模的扩大,用户往往需要在不同的应用系统之间频繁切换,而无须每次都进行身份验证。为了实现这种便捷的用户体验,SSO 技术应运而生。

CAS(Central Authentication Service)作为一种常用的单点登录解决方案,因其开源、易于扩展、以及与多个认证框架的良好兼容性,得到了广泛的应用。而在企业级开发中,Spring Security 则是保护 Java 应用安全性的不二选择。因此,如何将 CAS 和 Spring Security 有效整合,实现一个灵活、稳定的单点登录系统,是每个 Java 开发者都值得深入探讨的课题。

在本文中,我们将通过简单易懂的步骤,带领大家完成一个基于 Spring Security + CAS 的单点登录方案实现。无论您是初次接触 SSO,还是有一定经验的开发者,都能通过本篇教程快速掌握 CAS 的基本原理、部署方式,以及如何通过 Spring Security 实现应用的统一认证。同时,我们还会进行功能测试,确保单点登录效果满足预期。

2. CAS单点登录原理

在深入实施 CAS 和 Spring Security 整合之前,了解 CAS 的工作原理非常重要。CAS(Central Authentication Service)是一种集中式认证服务,它的主要作用是通过提供一个统一的认证中心,实现多个应用系统间的单点登录功能。在这个过程中,用户只需要在 CAS 认证中心登录一次,即可访问所有已授权的应用系统。

2.1. 核心概念

在理解 CAS 的单点登录原理时,有几个核心概念需要熟悉:

  • TGT (Ticket Granting Ticket)由 CAS 认证中心生成并存储在 CAS 服务器上的票据,用于标识用户的登录状态。用户成功登录后,TGT 会保存在用户的浏览器中,以便后续在访问其他应用系统时可以直接获取 ST

  • ST (Service Ticket)在用户访问具体的应用系统时,由 CAS 认证中心生成的临时票据,标识用户对该应用系统的访问权限。ST 一次性有效,用于实现一次认证即授权。

  • LT (Login Ticket)在用户登录 CAS 认证中心时生成的临时票据,用于防止表单重复提交。

  • Proxy Ticket (PT)在特定场景下,允许一个应用代表用户访问其他服务,此时会使用代理票据机制。

2.2. CAS单点登录流程

CAS 的单点登录流程主要包括以下步骤:

  1. 用户访问应用系统:用户首先访问需要登录的应用系统,该应用系统发现用户尚未登录,于是将用户重定向到 CAS 认证中心。

  2. 用户登录 CAS 认证中心:用户在 CAS 认证中心输入用户名和密码进行登录。CAS 认证中心验证用户的身份信息,通过验证后,生成一个 TGT(Ticket Granting Ticket)用于标识用户的登录状态,并生成一个 ST(Service Ticket)来授权用户访问目标应用系统。

  3. CAS 将用户重定向回应用系统:在用户登录成功后,CAS 认证中心将用户重定向回应用系统,并携带 ST 作为参数。

  4. 应用系统验证 Service Ticket:应用系统接收到 ST 后,将其发送到 CAS 认证中心进行验证。如果验证通过,应用系统认为用户已通过认证,从而允许用户访问系统资源。应用系统还会在本地创建用户的会话,方便用户的后续访问。

  5. 其他应用系统单点登录:当用户登录一个应用系统后,再次访问其他已配置为 SSO 的应用时,应用系统会自动通过 CAS 认证,获取到用户的身份信息,而不再需要用户重新登录。

3. CAS Server 部署

3.1. 配置Tomcat支持HTTPS协议

1. 生成秘钥库

我们可以使用 JDK 自带的 keytool 工具生成密钥库。首先,指定别名为 xfc(可以自定义别名),然后将密钥库存储在路径 D:\cas\keystore 中。执行以下命令即可生成密钥库:

keytool -genkey -v -alias xfc -keyalg RSA -keystore D:\cas\keystore\xfc.keystore

这条命令将生成一个别名为 xfc 的 RSA 加密密钥库,并将其保存在指定路径。

执行完毕会生成以下文件:

2. 从秘钥库里导出证书

基于生产的密钥库,我们需要从密钥库中导出证书,可以使用 keytool 工具执行以下命令:

keytool -export -trustcacerts -alias xfc -file D:/cas/keystore/xfc.cer -keystore D:/cas/keystore/xfc.keystore

在执行此命令时,需要输入在第一步创建密钥库时设置的密码,例如:666。该命令会从路径 D:/cas/keystore/xfc.keystore 中的密钥库导出别名为 xfc的证书,并将其保存为 D:/cas/keystore/xfc.cer 文件。

3. 将证书导入到JDK证书库

接下来就是将证书导入到 JDK 的证书库中,可以使用以下 keytool 命令:

keytool -import -trustcacerts -alias xfc -file D:/cas/keystore/xfc.cer -keystore "F:/environment/java/jre1.8.0_301/lib/security/cacerts"

执行该命令时,指定证书的别名为 xfc,将位于 D:/cas/keystore/xfc.cer 的证书文件导入到 JDK 的信任证书库 cacerts 中,路径为 F:/environment/java/jre1.8.0_301/lib/security/cacerts。导入过程中可能会提示输入密码,默认密码通常为 changeit。

4. tomcat配置https支持

为了在 Tomcat 9 中配置 HTTPS 支持,可以按照以下步骤进行。

首先,找到 Tomcat 安装目录中的 conf 文件夹,并找到 server.xml 文件。打开该文件,并在其中添加以下配置来启用 HTTPS 支持:

<Connector port="8445" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="D:\cas\keystore\xfc.keystore" keystorePass="666666" />

这段配置将 HTTPS 连接器绑定到 8443 端口,并指向了之前生成的密钥库文件 D:\cas\keystore\xfc.keystore,密码为 666666

配置完成后,可以启动 Tomcat 的 bin 目录下的 startup.bat 文件来运行 Tomcat。

如果在启动过程中遇到控制台输出中文乱码的情况,可以进入 Tomcat 目录下的 conf 文件夹,找到一个名为 logging.properties 的文件,打开该文件,找到以下配置项:

java.util.logging.ConsoleHandler.encoding = UTF-8

将 UTF-8 修改为 GBK,使修改后的配置如下:

java.util.logging.ConsoleHandler.encoding = GBK

保存文件后,重启 Tomcat,即可解决中文乱码的问题。

5. 打开tomcat网址

到这步Tomcat支持 Https协议就配置成功了。

3.2. CAS Server服务器搭建

3.2.1. CAS Server war下载

在本文中我们需要下载cas-server-webapp-tomcat-5.3.14:
Central Repository: org/apereo/cas/cas-server-webapp-tomcat/5.3.14

3.2.2. CAS Server war发布到tomcat

把war包放tomcat下,启动tomcat会自动解压,我们把名称改成cas,方便访问:

访问https://xfc.com:8445/cas/login(这个根据你自己的配置)

3.2.3. 配置数据源,数据库用户认证

1. 新建数据表:

```sql
CREATE DATABASE `db_sso`;

USE `db_sso`;

/* Table structure for table `t_cas` */

DROP TABLE IF EXISTS `t_cas`;

CREATE TABLE `t_cas` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(30) DEFAULT NULL,
  `password` VARCHAR(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

/* Data for the table `t_cas` */

INSERT INTO `t_cas` (`id`, `username`, `password`) VALUES (1, 'xfc', '123456');

```

2. 修改CAS Server的application.properties配置文件

进入cas目录修改配置文件:

3. 注释写死的用户名和密码,加上jdbc数据源配置:

# cas.authn.accept.users=casuser::Mellon

# cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQL5Dialect

cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/db_sso?serverTimezone=GMT

cas.authn.jdbc.query[0].user=root

cas.authn.jdbc.query[0].password=123456

cas.authn.jdbc.query[0].sql=select * from t_cas where username=?

cas.authn.jdbc.query[0].fieldPassword=password

cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver

4. 加上jdbc驱动及相关支持jar包

进入F:\environment\apache-tomcat-9.0.53\webapps\cas\WEB-INF\lib(你自己cas的目录),粘贴以下jar包:

3.2.4.  密码加密校验

1. 将原数据库密码进行MD5加密

SELECT MD5('123456');

2. 修改CAS Server的application.properties配置文件

在配置文件末尾加上:

cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT

cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8

#MD5加密策略

cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5

输入用户名和密码后进入这个界面就是配置成功了:

4. SpringSecurity 整合 CAS

4.1. SpringSecurity集成CAS单点登录认证流程

以下为SpringSecurity集成CAS单点登录的认证流程:

  1. 用户访问保护资源 用户请求访问Spring Security保护的应用资源。如果用户未经验证,Spring Security的拦截器将拦截此请求。
  2. 重定向到CAS登录Spring Security配置的CAS入口点CasAuthenticationEntryPoint将识别到用户未登录,并重定向用户到CAS服务器的登录页面。
  3. 用户在CAS登录 用户在CAS登录页面输入凭据并提交。CAS服务器验证用户凭据,如果凭据正确,CAS将用户重定向回Spring Security应用,同时附带一个票据(通常是一个Service Ticket)。
  4. 票据验证用户返回到应用时,带有从CAS服务器获得的票据。Spring Security现在需要验证这个票据以确保它是有效的。这一步由配置的票据验证器如Cas30ServiceTicketValidator)完成,它将与CAS服务器通信以验证票据的有效性。
  5. 创建Security Context 一旦票据被验证为有效,CAS认证提供者CasAuthenticationProvider将基于从CAS服务器返回的用户数据创建一个认证对象。这个认证对象被用来填充Spring Security的Security Context,从而标记用户为已认证。
  6. 授权与资源访问用户现在被认为是经过验证的,Spring Security将根据用户的权限评估用户对请求资源的访问。如果用户有权访问,请求将继续处理;如果没有访问权限,将返回一个访问拒绝的错误。
  7. 后续请求与单点登录用户在初次登录后,随后的请求通常不需要重新认证。CAS和Spring Security支持会话的创建,所以用户可以在不再次输入凭据的情况下访问其他受保护的资源。
  8. 登出处理当用户从任一应用发起登出请求时,Spring Security将确保从应用和CAS服务器上都清除会话。通常,这也会导致所有使用CAS进行单点登录的其他应用会话被终止。

通过这个流程,Spring Security利用CAS实现了一个安全的单点登录解决方案,允许用户在多个相互信任的应用间无缝地进行身份认证和授权。

4.2. 版本依赖

SpringSecurity集成CAS的Maven依赖如下(SpringBoot版本为2.6.3):

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-cas</artifactId>
            <version>5.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.jasig.cas.client</groupId>
            <artifactId>cas-client-core</artifactId>
            <version>3.6.4</version>
        </dependency>

版本很重要,如果版本不匹配会报错!! 

4.3. 核心代码

4.3.1. 后端代码

yml配置:

server:
  servlet:
    context-path: "/test"
  port: 7888

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cas?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

cas:
  server: https://java1234.com:8443/cas
  client: http://localhost:7888/test

编写CustomUserDetailsService用于从cas令牌中加载用户信息:

@Service
public class CustomUserDetailsService implements AuthenticationUserDetailsService<CasAssertionAuthenticationToken> {
    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService roleService;

    @Override
    public UserDetails loadUserDetails(CasAssertionAuthenticationToken token)
            throws UsernameNotFoundException {
        SysUser user = userService.getUserByUserName(token.getName());
        if (Objects.isNull(user)) {
            throw new RuntimeException("用户不存在");
        }
        List<String> roles =  roleService.getRolesByUserName(token.getName());
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }

        return new AuthUser(user.getUsername(), user.getPassword(), user.getIsEnabled(), authorities);
    }


}

这段代码定义了一个服务CustomUserDetailsService,它实现了用于Spring Security的AuthenticationUserDetailsService接口,专门处理通过CAS单点登录系统验证后的用户。该服务通过从CAS认证令牌获取用户名,调用用户服务以检索用户详细信息,从角色服务获取用户角色,并将这些角色转换为Spring Security需要的权限格式,最后创建并返回一个包含用户凭据和权限的UserDetails对象供Spring Security进一步处理认证和授权。 

编写WebSecurityConfigurer:

package com.xfc.auth.configuration.auth;


import com.xfc.auth.service.CustomUserDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.cas.web.CasAuthenticationFilter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

@Slf4j
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    // 配置文件中的CAS服务器地址
    @Value("${cas.server}")
    private String casServerUrl;

    // 配置文件中的本应用前端地址
    @Value("${cas.client}")
    private String casClientUrl;

    private static final String[] PERMIT_URL = new String[]{"/login/cas", "/logout/cas"};

   @Autowired
   CustomUserDetailsService customUserDetailsService;

    /**
     * SpringSecurity配置
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                // 配置接口过滤网,放行/login/cas用于单点登录的验证
                .authorizeRequests()
                .antMatchers(PERMIT_URL).permitAll()
                .anyRequest().authenticated()
                .and().httpBasic()
                // 配置自定义的用户认证入口类(用于处理未登录或登录超时的逻辑)
                .authenticationEntryPoint(casAuthenticationEntryPoint())
                .and()
                // 配置自定义的CAS用户认证入口类
                .addFilter(casAuthenticationFilter())
                // 配置CAS需要用到的其他类
                .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class)
                .addFilterBefore(casLogoutFilter(), LogoutFilter.class)
                // 禁用CORS
                // 禁用CSRF
                .csrf().disable();
    }

    /**
     * CAS配置(AuthenticationProvider)
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
        auth.authenticationProvider(casAuthenticationProvider());
    }

    /**
     * CAS:认证入口
     */
    @Bean
    public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
        CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
        casAuthenticationEntryPoint.setLoginUrl(casServerUrl + "/login");
        casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
        return casAuthenticationEntryPoint;
    }

    /**
     * CAS:服务配置
     */
    @Bean
    public ServiceProperties serviceProperties() {
        ServiceProperties serviceProperties = new ServiceProperties();
        // 此处填入前端登录页面的地址
        serviceProperties.setService(casClientUrl + "/#/login/cas");
        serviceProperties.setAuthenticateAllArtifacts(true);
        return serviceProperties;
    }

    /**
     * CAS:配置自定义的CAS用户认证入口类
     */
    @Bean
    public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
        CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
        casAuthenticationFilter.setAuthenticationManager(authenticationManager());
        casAuthenticationFilter.setFilterProcessesUrl("/login/cas");
        casAuthenticationFilter.setServiceProperties(serviceProperties());
        // 重要:此处为配置ticket验证成功后的逻辑,默认为重定向到首页,因前后端分离,仅需要返回成功即可。
        casAuthenticationFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            response.setStatus(HttpServletResponse.SC_OK);
            PrintWriter out = response.getWriter();
            out.write("{\"status\":" + "\"200\"" + "}");
        });
        casAuthenticationFilter.setAuthenticationFailureHandler((request, response, e) -> {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            PrintWriter out = response.getWriter();
            out.write("{\"code\":401" + ",\"message\":\"Ticket verified failed!\"}");
            log.error("单点登录验证失败", e);
        });
        return casAuthenticationFilter;
    }

    /**
     * CAS:CAS的核心,CasAuthenticationProvider
     */
    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
        casAuthenticationProvider.setAuthenticationUserDetailsService(customUserDetailsService());
        casAuthenticationProvider.setServiceProperties(serviceProperties());
        casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
        casAuthenticationProvider.setKey("EXAMPLE_CAS_PROVIDER");
        return casAuthenticationProvider;
    }

    /**
     * CAS:自定义的用户认证入口类(用于处理未登录或登录超时的逻辑)
     */
    @Bean
    public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> customUserDetailsService() {
        return customUserDetailsService;
    }

    /**
     * CAS:ticket验证类
     */
    @Bean
    public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
        return new Cas20ServiceTicketValidator(casServerUrl);
    }

    /**
     * CAS:SingleSignOutFilter
     */
    @Bean
    public SingleSignOutFilter singleSignOutFilter() {
        SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
        singleSignOutFilter.setIgnoreInitConfiguration(true);
        return singleSignOutFilter;
    }

    /**
     * CAS:LogoutFilter
     */
    @Bean
    public LogoutFilter casLogoutFilter() {
        LogoutFilter logoutFilter = new LogoutFilter(casServerUrl + "/logout?service=" + casClientUrl,
                new SecurityContextLogoutHandler());
        logoutFilter.setFilterProcessesUrl("/logout/cas");
        return logoutFilter;
    }

}

这个类是一个配置类,它使用CAS来进行单点登录(SSO)认证。下面详细解释这个配置类中的核心代码及其功能:

  1. 通过 CasAuthenticationEntryPoint 配置了CAS服务的登录URL,并通过设置服务属性定义了如何与CAS服务器进行交互。

  2. ServiceProperties 设置服务的回调URL,即CAS登录成功后重定向到客户端的地址,并确保所有artifact都经过认证。

  3. CasAuthenticationFilter 设置认证管理器处理认证过程,并配置成功和失败的处理器,定制认证成功或失败后的行为。

  4. CasAuthenticationProvider 配置了用来加载用户特定数据的 AuthenticationUserDetailsService 和票据验证器 Cas20ServiceTicketValidator 用于校验从CAS服务器返回的票据。

  5. SingleSignOutFilter 用于处理CAS单点登出,保证从CAS服务登出时客户端会话也能同步失效。

  6. LogoutFilter 定义了CAS服务的登出过程,确保正确重定向到CAS服务器进行登出。

后端的集成就完成了,是不是很简单。

4.3.2. 前端代码

前端代码我就不贴了(前端不熟),结尾两个参考文章都有前端代码。

5. 结语

通过本文的示例,我们成功完成了 Spring Security 集成 CAS 单点登录的基础配置,实现了用户在多应用间无缝切换的认证体验。Spring Security 与 CAS 的结合不仅提升了系统的安全性和扩展性,也简化了复杂应用环境下的用户管理流程。这种集成方案对于分布式系统或微服务架构尤其适用。

下一期,我们将进一步探讨进阶版内容,涵盖更复杂的应用场景——将小程序的登录认证集成到这个单点登录系统中。届时,我们将深入讲解如何让移动端用户通过小程序完成统一的身份认证,敬请期待!

6. 参考链接

Spring Security整合CAS_spring-security-cas-CSDN博客

SprinBoot(SpringSecurity)+前后端分离 集成CAS单点登录 - 简书

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot编程训练系统:构建可扩展的应用

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了编程训练系统的开发全过程。通过分析编程训练系统管理的不足&#xff0c;创建了一个计算机管理编程训练系统的方案。文章介绍了编程训练系统的系统分析部分&…

提升AI性能的关键大型语言模型(LLM)压缩策略

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

「IDE」集成开发环境专栏目录大纲

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「IDE」集成开发环境&#x1f4da;全部专栏「Win」Windows程序设计「IDE」集成开发环境「UG/NX」BlockUI集合「C/C」C/C程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「UG/NX」NX定…

关于 npm 更新镜像源问题

npm&#xff08;Node Package Manager&#xff09;&#xff0c;是一个NodeJS包管理和分发工具&#xff0c;已经成为了非官方的发布Node模块&#xff08;包&#xff09;的标准。&#xff09; 查看当前npm版本 npm -v 10.9.0 执行以下命令报错 npm install --registryhttp…

Worldly平台更新Higg FEM 2024模块价格及购买指南

近日&#xff0c;LEVERAGE供应链管理从美国可持续服装联盟&#xff08;Cascale&#xff09;验证官方Worldly平台模块订阅更新中获悉&#xff0c;FEM2024模块价格更新的重要信息。此次更新涉及工厂环境模块&#xff08;FEM&#xff09;和工厂社会劳工模块&#xff08;FSLM&#…

MQ的实际使用

前言: 在这一篇文章当中我会以RcoketMQ来对其的使用的场景进行一个仔细地说明,这个里面也会涉及到一些额外的知识,看完之后对面试而言的话那么就是直接拿捏,当然在看这篇文章之前要先看MQ的基础知识-CSDN博客 毕竟基础才是王道,下面就是开始我们的正菜 在我的基础的那篇文章中就…

MFC图形函数学习08——绘图函数的重载介绍

在《MFC图形函数学习06——画椭圆弧线函数》中介绍了CPoint类、POINT结构体&#xff1b;在《MFC图形函数学习07——画扇形函数》中介绍了CRect类、RECT结构体。在介绍完后&#xff0c;没有介绍它们怎样使用。实际上&#xff0c;这些类和结构体对象或指针也是我们学习过的绘图函…

SAP-ABAP开发-BAPI

BAPI基于数据库表的操作函数传入传出数据&#xff0c;本身函数有接口与增强无关 目录 一、BAPI接口定义 二、业务对象 三、查询方法 四、调用 五、BAPI创建 &#xff08;1&#xff09;在DDIC中创建一个结构 &#xff08;2&#xff09;创建BAPI函数模块和函数或API方法 …

Ceph MDS高可用架构探索:从零到一构建多主一备MDS服务

文章目录 Ceph实现MDS服务多主一备高可用架构当前 mds 服务器状态添加 MDS 服务器验证ceph集群当前状态当前的文件系统状态设置处于激活状态 mds 的数量MDS 高可用优化分发配置文件并重启 mds 服务 Ceph实现MDS服务多主一备高可用架构 Ceph 的元数据服务&#xff08;MDS&#…

python实战(八)——情感识别(多分类)

一、任务目标 本文使用的是来自Kaggle的一个情感识别数据集&#xff0c;这个数据集的总数据量是5934条&#xff0c;标签为anger、fear、joy三种情感的其中一种&#xff0c;很明显是一个多分类任务。这里&#xff0c;我们将使用微调技巧进行深度学习建模&#xff0c;同时我们会比…

价格战背后:即时零售三小龙的致命伤

价格战&#xff0c;从来就不仅仅是低价&#xff0c;低价前面永远要加上定语&#xff1a;确保品质和服务的。价格战是减法&#xff0c;更是加法。减去的是价格水分&#xff0c;加上的是品质和服务保障。 转载|原创新熵 作者丨宜新 编辑丨赛柯 今年双十一的热点&#xff0c;让人…

sd1.5/sdxl的推理,训练

1.sd1.5/sdxl的推理 主要讲述一下unet的降噪&#xff0c;以及采样器的作用&#xff0c;已sd1.5为例&#xff0c;sdxl类似 unet的降噪过程中&#xff0c;如20步降噪&#xff0c;这20个unet共用的一个权重 1.1 timesteps 根据unet的降噪步数&#xff0c;即num_inference_steps…

有哪些工具可以快速压缩图片呢?分享三个简单好用的图片压缩工具

现在的图片经常会因为图片过大的问题&#xff0c;影响在网上的上传使用&#xff0c;一般在平台上传图片时需要比较小的图片。但是随着现在图片质量的提升&#xff0c;导致图片的文件也越来越大&#xff0c;想要缩小图片大小&#xff0c;可以选择使用压缩图片的方法来处理。下面…

Java集合 List——针对实习面试

目录 Java集合 ListJava List的三种主要实现是什么&#xff1f;它们各自的特点是什么&#xff1f;Java List和Array&#xff08;数组&#xff09;的区别&#xff1f;Java List和Set有什么区别&#xff1f;ArrayList和Vector有什么区别&#xff1f;什么是LinkedList&#xff1f;…

请求接口时跨域问题详细解决方案

浏览器中的报错&#xff1a; 跨域问题通常需要前端和后端协作解决。以下是一些常用的解决方法&#xff0c;分别从前端和后端的角度进行讲解&#xff1a; 一. 后端解决方案 设置 CORS 头部&#xff1a; 最常用和推荐的方法是后端服务器设置 Access-Control-Allow-Origin 响应头…

同三维T610UDP-4K60 4K60 DP或HDMI或手机信号采集卡

1路DP/HDMI/TYPE-C&#xff08;手机/平板等&#xff09;视频信号输入1路MIC1路LINE OUT,带1路HDMI环出&#xff0c;USB免驱&#xff0c;分辨率4K60&#xff0c;可采集3路信号中其中1路&#xff0c;按钮切换&#xff0c;可采集带TYPE-C接口的各品牌手机/平板/笔记本电脑等 同三维…

初级数据结构——顺序表

目录 前言一、定义与特点二、类型三、基本操作四、应用场景五、优缺点六、元素插入和删除动态图解插入删除 七、代码模板八、使用顺序表的经典例题1.求奇数的乘积代码题解 2.数值统计代码题解 九、总结结语 前言 顺序表示最基础的数据结构之一&#xff0c;它也是我们学习开始学…

arkUI:遍历数据数组动态渲染(forEach)

arkUI&#xff1a;遍历数据数组动态渲染&#xff08;forEach&#xff09; 1 主要内容说明2 相关内容2.1 ForEach 的基本语法2.2 简单遍历数组2.2 多维数组遍历2.4 使用唯一键2.5 源码1的相关说明2.5.1 源码1 &#xff08;遍历数据数组动态渲染&#xff09;2.5.2 源码1运行效果 …

新的恶意软件活动通过游戏应用程序瞄准 Windows 用户

一种新的恶意软件 Winos4.0 被积极用于网络攻击活动。FortiGuard实验室发现&#xff0c;这种先进的恶意框架是从臭名昭著的 Gh0strat 演变而来的&#xff0c;配备了模块化组件&#xff0c;可在受感染的设备上进行一系列恶意活动。 这些攻击已在游戏相关应用程序中发现&#xf…

Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上

一、Maven介绍 Maven 是一款为 Java 项目管理构建、依赖管理的工具&#xff08;软件&#xff09;&#xff0c;使用 Maven 可以自动化构建、测试、打包和发布项目&#xff0c;大大提高了开发效率和质量。 二、Maven安装步骤 1.下载后解压到没有空格、特殊字符和中文的目录中 2…