SpringSecurity中文文档(Servlet CAS)

CAS Authentication

Overview

JA-SIG 生产了一个名为 CAS 的企业级单点登录系统。与其它倡议不同,JA-SIG 的中央认证服务是开源的,广泛使用,易于理解,平台独立,并支持代理功能。Spring Security 完全支持 CAS,并为从单个应用程序部署的 Spring Security 迁移到由企业级 CAS 服务器保护的多个应用程序部署提供了简单的迁移路径。

你可登入 www.apereo.org 了解更多有关 CAS 的资料。您还需要访问此站点来下载 CAS 服务器文件。

How CAS Works

尽管 CAS 网站包含详细描述 CAS 架构的文档,但在这里我们再次概述 CAS 的通用概念,以 Spring Security 的背景呈现。Spring Security 3.x 支持 CAS 3。在撰写本文时,CAS 服务器处于版本 3.4。

在您的企业中,您将需要设置一个 CAS 服务器。CAS 服务器只是一个标准的 WAR 文件,因此设置服务器并不困难。在 WAR 文件中,您可以自定义显示给用户的登录和其他单点登录页面。

当部署 CAS 3.4 服务器时,您还需要在 CAS 提供的 deployerConfigContext.xml 中指定一个 AuthenticationHandler。AuthenticationHandler 有一个简单的返回布尔值的方法,以确定一组给定的凭据是否有效。您的 AuthenticationHandler 实现需要与某种后端认证存储库链接,例如 LDAP 服务器或数据库。CAS 本身包含了多种 AuthenticationHandler 以协助此操作。当您下载并部署服务器 WAR 文件时,它被设置为成功验证输入匹配其用户名的密码的用户,这对于测试很有用。

除了 CAS 服务器本身之外,当然还有部署在您企业中的其他关键参与者,即“服务”的安全 Web 应用程序。这些 Web 应用程序分为三种类型。那些可以验证服务票据的服务,那些可以获取代理票据的服务,以及那些可以验证代理票据的服务。验证代理票据有所不同,因为必须验证代理列表,并且代理票据通常可以重复使用。

Spring Security and CAS Interaction Sequence

Web 浏览器、 CAS 服务器和 Spring Security 安全服务之间的基本交互如下:

  • Web 用户正在浏览服务的公共页面。CAS 或 Spring Security 并未参与。
  • 用户最终请求的页面要么是安全的,要么使用的 bean 之一是安全的。Spring Security 的 ExceptionTransationFilter 将检测 AccessDeniedException 或 AuthenticationException。
  • 由于用户的 Authentication 对象(或缺少 AuthenticationException)导致 AuthenticationException,ExceptionTransationFilter 将调用配置的 AuthenticationEntryPoint。如果使用 CAS,这将是 CasAuthenticationEntryPoint 类。
  • CasAuthenticationEntryPoint 将用户的浏览器重定向到 CAS 服务器。它还将指示一个服务参数,该参数是 Spring Security 服务(您的应用程序)的回调 URL。例如,浏览器被重定向到的 URL 可能是 my.company.com/cas/login?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Flogin/cas.
  • 当用户的浏览器重定向到 CAS 时,他们将被告知输入用户名和密码。如果用户提供了表明他们之前登录的会话 Cookie,他们就不会再次被提示登录(我们将稍后讨论这一程序的例外情况)。CAS 将使用上述讨论的 PasswordHandler(或 AuthenticationHandler,如果使用 CAS 3.0)来决定用户名和密码是否有效。
  • 登录成功后,CAS 将重定向用户的浏览器回到原始服务。它还将包括一个 ticket 参数,这是一个表示“服务票据”的不可见字符串。继续我们之前的例子,浏览器被重定向到的 URL 可能是 server3.company.com/webapp/login/cas?ticket=ST-0-ER94xMJmn6pha35CQRoZ。
  • 在服务 Web 应用程序中,CasAuthenticationFilter 始终监听 /login/cas 的请求(这是可配置的,但在本介绍中我们将使用默认值)。处理过滤器将构建一个代表服务票据的 UsernamePasswordAuthenticationToken。主体将等于 CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER,而凭据将是服务票据的不可见值。然后,这个认证请求将交给配置的 AuthenticationManager。
  • AuthenticationManager 实现将是 ProviderManager,后者又通过 CasAuthenticationProvider 进行配置。CasAuthenticationProvider 只响应包含 CAS 特定主体(如 CasAuthenticationFilter.CAS_STATEFUL_IDENTIFIER)和 CasAuthenticationTokens(稍后将讨论)的 UsernamePasswordAuthenticationTokens。
  • CasAuthenticationProvider 将使用 TicketValidator 实现来验证服务票据。这通常是一个 Cas20ServiceTicketValidator,它是 CAS 客户端库中包含的类之一。在应用程序需要验证代理票据的情况下,使用 Cas20ProxyTicketValidator。TicketValidator 通过 HTTPS 请求向 CAS 服务器验证服务票据。它还可能包括一个代理回调 URL,这在示例中包含:my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver3.company.com%2Fwebapp%2Flogin/cas&ticket=ST-0-ER94xMJmn6pha35CQRoZ&pgtUrl=https://server3.company.com/webapp/login/cas/proxyreceptor。
  • 在 CAS 服务器上,验证请求将被接收。如果呈现的服务票据与服务 URL 匹配,CAS 将提供 XML 格式的肯定响应,指示用户名。如果认证过程中涉及任何代理(下面讨论),代理列表也将包括在 XML 响应中。
  • [可选] 如果请求 CAS 验证服务时包括代理回调 URL(在 pgtUrl 参数中),CAS 将包含一个 pgtIou 字符串在 XML 响应中。这个 pgtIou 代表一个代理授予票据 IOU。然后,CAS 服务器将创建自己的 HTTPS 连接返回 pgtUrl。这是为了相互认证 CAS 服务器和声称的服务 URL。HTTPS 连接将用于将代理授予票据发送给原始 Web 应用程序。例如,server3.company.com/webapp/login/cas/proxyreceptor?pgtIou=PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt&pgtId=PGT-1-si9YkkHLrtACBo64rmsi3v2nf7cpCResXg5MpESZFArbaZiOKH。
  • Cas20TicketValidator 将解析 CAS 服务器返回的 XML。它将返回给 CasAuthenticationProvider 一个 TicketResponse,包括用户名(强制性)、代理列表(如果涉及代理)和代理授予票据 IOU(如果请求了代理回调)。
  • 接下来 CasAuthenticationProvider 将调用一个配置的 CasProxyDecider。CasProxyDecider 指示 TicketResponse 中的代理列表是否被服务接受。Spring Security 提供了几个实现:RejectProxyTickets、AcceptAnyCasProxy 和 NamedCasProxyDecider。这些名称大多不言自明,除了 NamedCasProxyDecider,它允许提供一个受信任代理的列表。
  • CasAuthenticationProvider 接下来将请求 AuthenticationUserDetailsService 加载应用于 Assertion 中包含的用户的 GrantedAuthority 对象。
  • 如果没有问题,CasAuthenticationProvider 将构造一个 CasAuthenticationToken,其中包含 TicketResponse 和 GrantedAuthoritys 中包含的详细信息。
  • 控件然后返回到 CasAuthenticationFilter,它将创建的 CasAuthenticationToken 放置在安全上下文中。
  • 用户的浏览器被重定向到导致 AuthenticationException 的原始页面(或者根据配置而定的自定义目标)。

您还在这里真是太好了! 现在让我们看看如何配置它

Configuration of CAS Client

由于 Spring Security,CAS 的 Web 应用程序端变得简单。假设您已经了解使用 Spring Security 的基础知识,因此这些内容在此不再重复。我们将假设正在使用基于命名空间的配置,并根据需要添加 CAS beans。每个部分都建立在前面部分的基础上。完整的 CAS 示例应用程序可以在 Spring Security Samples 中找到。

Service Ticket Authentication

本节介绍如何设置 SpringSecurity 以验证服务票证。通常情况下,这就是 Web 应用程序所需要的全部内容。您需要将 ServiceProperties bean 添加到应用程序上下文中。这代表你的民安队服务:

<bean id="serviceProperties"
	class="org.springframework.security.cas.ServiceProperties">
<property name="service"
	value="https://localhost:8443/cas-sample/login/cas"/>
<property name="sendRenew" value="false"/>
</bean>

服务必须等于一个 URL,该 URL 将由 CasAuthenticationFilter 监控。sendRenew 的默认值为 false,但如果您的应用程序特别敏感,应该将其设置为 true。这个参数的作用是告诉 CAS 登录服务单点登录登录是不可接受的。相反,用户需要重新输入他们的用户名和密码,才能访问服务。

应该将下列 bean 配置为启动 CAS 身份验证过程(假设您使用的是名称空间配置) :

<security:http entry-point-ref="casEntryPoint">
...
<security:custom-filter position="CAS_FILTER" ref="casFilter" />
</security:http>

<bean id="casFilter"
	class="org.springframework.security.cas.web.CasAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>

<bean id="casEntryPoint"
	class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<property name="loginUrl" value="https://localhost:9443/cas/login"/>
<property name="serviceProperties" ref="serviceProperties"/>
</bean>

为了使 CAS 运行,ExceptionTranslationFilter 的 authenticationEntryPoint 属性必须设置为 CasAuthenticationEntryPoint bean。这可以通过使用 entry-point-ref 轻松完成,如上面的示例所示。CasAuthenticationEntryPoint 必须引用 ServiceProperties bean(如上所述),该 bean 提供企业 CAS 登录服务器的 URL。用户浏览器将被重定向到这个位置。

CasAuthenticationFilter 具有与 UsernamePasswordAuthenticationFilter (用于基于表单的登录)非常相似的属性。您可以使用这些属性来自定义诸如身份验证成功和失败的行为之类的事情。

接下来,您需要添加 CasAuthenticationProvider 及其合作者:

<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="casAuthenticationProvider" />
</security:authentication-manager>

<bean id="casAuthenticationProvider"
	class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<property name="authenticationUserDetailsService">
	<bean class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
	<constructor-arg ref="userService" />
	</bean>
</property>
<property name="serviceProperties" ref="serviceProperties" />
<property name="ticketValidator">
	<bean class="org.apereo.cas.client.validation.Cas20ServiceTicketValidator">
	<constructor-arg index="0" value="https://localhost:9443/cas" />
	</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>

<security:user-service id="userService">
<!-- Password is prefixed with {noop} to indicate to DelegatingPasswordEncoder that
NoOpPasswordEncoder should be used.
This is not safe for production, but makes reading
in samples easier.
Normally passwords should be hashed using BCrypt -->
<security:user name="joe" password="{noop}joe" authorities="ROLE_USER" />
...
</security:user-service>

CasAuthenticationProvider 使用 UserDetailsService 实例加载用户的权限,一旦这些权限经过 CAS 的身份验证。我们在这里展示了一个简单的内存设置。请注意,CasAuthenticationProvider 实际上并不使用密码进行身份验证,而是使用权限。

如果您回过头来参考 CAS 如何工作一节,那么这些 bean 都是相当不言自明的。

这就完成了 CAS 最基本的配置。如果您没有犯任何错误,您的 Web 应用程序应该在 CAS 单点登录的框架内工作。Spring Security 的其他部分不需要关心 CAS 处理身份验证的事实。在下面的部分中,我们将讨论一些(可选的)更高级的配置。

Single Logout

CAS 协议支持单一注销,可以很容易地添加到您的 Spring 安全配置中。下面是对处理单次注销的 Spring Security 配置的更新

<security:http entry-point-ref="casEntryPoint">
...
<security:logout logout-success-url="/cas-logout.jsp"/>
<security:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER"/>
<security:custom-filter ref="singleLogoutFilter" before="CAS_FILTER"/>
</security:http>

<!-- This filter handles a Single Logout Request from the CAS Server -->
<bean id="singleLogoutFilter" class="org.apereo.cas.client.session.SingleSignOutFilter"/>

<!-- This filter redirects to the CAS Server to signal Single Logout should be performed -->
<bean id="requestSingleLogoutFilter"
	class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="https://localhost:9443/cas/logout"/>
<constructor-arg>
	<bean class=
		"org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout/cas"/>
</bean>

logout 元素将用户从本地应用程序中注销,但不结束与 CAS 服务器或其他应用程序的会话。requestSingleLogoutFilter 过滤器将允许 /spring_security_cas_logout 的 URL 被请求,以将应用程序重定向到配置的 CAS 服务器注销 URL。然后 CAS 服务器将向所有已登录的服务发送单点注销请求。singleLogoutFilter 通过查找静态 Map 中的 HttpSession 并使其无效来处理单点注销请求。

为什么同时需要注销元素和 singleLogoutFilter 可能会令人困惑。最佳做法是首先在本地注销,因为 SingleSignOutFilter 只是将 HttpSession 存储在静态 Map 中,以便在其上调用无效。使用上面的配置,注销的流程将是:

  • 用户请求/注销,这将使用户退出本地应用程序,并将用户发送到注销成功页面。
  • 注销成功页面/cas-logout。Jsp,应该指示用户单击指向/logout/cas 的链接,以退出所有应用程序。
  • 当用户单击链接时,用户被重定向到 CAS 单个注销 URL (localhost: 9443/CAS/logout)。
  • 在 CAS 服务器端,CAS 单一注销 URL 然后向所有 CAS 服务提交单一注销请求。在 CAS 服务端,Apereo 的 SingleSignOutFilter 通过使原始会话无效来处理注销请求。

下一步是将以下内容添加到 web.xml 中

<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>
	org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
	<param-name>encoding</param-name>
	<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>
	org.apereo.cas.client.session.SingleSignOutHttpSessionListener
</listener-class>
</listener>

在使用 SingleSignOutFilter 时,您可能会遇到一些编码问题。因此,我们建议在使用 SingleSignOutFilter 时添加 <per_0> 。有关详细信息,请再次参考 Apereo CAS 的文档。SingleSignOutHttpSessionListener 确保在 HttpSession 过期时,删除用于单次注销的映射。

Authenticating to a Stateless Service with CAS

本节介绍如何使用 CAS 对服务进行身份验证。换句话说,本节讨论如何设置使用 CAS 身份验证服务的客户端。下一节将介绍如何设置无状态服务以使用 CAS 进行身份验证。

Configuring CAS to Obtain Proxy Granting Tickets

为了对无状态服务进行身份验证,应用程序需要获得一个代理授予票证(PGT)。本节描述如何配置 Spring Security 以在 thencas-st [ Service Ticket Authentication ]配置上获取 PGT 构建。

第一步是在 Spring 安全配置中包含一个 ProxyGrantingTicketStorage。这用于存储 CasAuthenticationFilter 获取的 PGT,以便可以使用它们获取代理票证。下面显示了一个示例配置

<!--
NOTE: In a real application you should not use an in memory implementation.
You will also want to ensure to clean up expired tickets by calling
ProxyGrantingTicketStorage.cleanup()
-->
<bean id="pgtStorage" class="org.apereo.cas.client.proxy.ProxyGrantingTicketStorageImpl"/>

下一步是更新 CasAuthenticationProvider,以便能够获得代理票证。为此,将 Cas20ServiceTicketValidator 替换为 Cas20ProxyTicketValidator。ProxyCallbackUrl 应该设置为应用程序将接收 PGT 的 URL。最后,配置还应该引用 ProxyGrantingTicketStorage,以便它可以使用 PGT 获取代理票证。您可以在下面找到应该进行配置更改的示例。

<bean id="casAuthenticationProvider"
	class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
...
<property name="ticketValidator">
	<bean class="org.apereo.cas.client.validation.Cas20ProxyTicketValidator">
	<constructor-arg value="https://localhost:9443/cas"/>
		<property name="proxyCallbackUrl"
		value="https://localhost:8443/cas-sample/login/cas/proxyreceptor"/>
	<property name="proxyGrantingTicketStorage" ref="pgtStorage"/>
	</bean>
</property>
</bean>

最后一步是更新 CasAuthenticationFilter 以接受 PGT 并将它们存储在 ProxyGrantingTicketStorage 中。重要的是,ProxyRecorUrl 与 Cas20ProxyTicketValidator 的 proxyCallbackUrl 匹配。下面显示了一个示例配置。

<bean id="casFilter"
		class="org.springframework.security.cas.web.CasAuthenticationFilter">
	...
	<property name="proxyGrantingTicketStorage" ref="pgtStorage"/>
	<property name="proxyReceptorUrl" value="/login/cas/proxyreceptor"/>
</bean>
Calling a Stateless Service Using a Proxy Ticket

既然 Spring Security 获得了 PGT,您就可以使用它们来创建代理票证,用于对无状态服务进行身份验证。CAS 示例应用程序包含 ProxyTicketSampleServlet 中的一个工作示例。示例代码如下:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
// NOTE: The CasAuthenticationToken can also be obtained using
// SecurityContextHolder.getContext().getAuthentication()
final CasAuthenticationToken token = (CasAuthenticationToken) request.getUserPrincipal();
// proxyTicket could be reused to make calls to the CAS service even if the
// target url differs
final String proxyTicket = token.getAssertion().getPrincipal().getProxyTicketFor(targetUrl);

// Make a remote call using the proxy ticket
final String serviceUrl = targetUrl+"?ticket="+URLEncoder.encode(proxyTicket, "UTF-8");
String proxyResponse = CommonUtils.getResponseFromServer(serviceUrl, "UTF-8");
...
}

Proxy Ticket Authentication

CasAuthenticationProvider 区分有状态和无状态客户端。有状态客户端被认为是任何提交到 CasAuthenticationFilter 的 filterProcessesUrl 的客户端。无状态客户端是在除 filterProcessesUrl 之外的 URL 上向 CasAuthenticationFilter 提出身份验证请求的任何客户端。

因为远程处理协议无法在 HttpSession 的上下文中显示它们自己,所以不可能依赖默认的实践,即在请求之间的会话中存储安全上下文。此外,由于 CAS 服务器在票证被 TicketValidator 验证之后会使票证无效,因此在后续请求上显示相同的代理票证将不起作用。

一个显而易见的选择是根本不使用 CAS 对协议客户端进行远程处理。然而,这将消除 CAS 的许多令人满意的特性。作为一种折衷方案,CasAuthenticationProvider 使用 StatelessTicketCache。这仅用于使用等于 CasAuthenticationFilter.CAS _ STATELSS _ IDENTIFIER 的主体的无状态客户端。CasAuthenticationProvider 将把结果 CasAuthenticationToken 存储在 StatelessTicketCache 中,并在代理票证上键入。因此,远程处理协议客户端可以提供相同的代理票据,CasAuthenticationProvider 不需要联系 CAS 服务器进行验证(除了第一个请求)。经过身份验证后,代理票据可以用于原始目标服务以外的 URL。

本节在前面几节的基础上构建,以适应代理票证身份验证。第一步是指定对所有工件进行身份验证,如下所示。

<bean id="serviceProperties"
	class="org.springframework.security.cas.ServiceProperties">
...
<property name="authenticateAllArtifacts" value="true"/>
</bean>

下一步是为 CasAuthenticationFilter 指定 serviceProperties 和 enticationDetailsSource。ServiceProperties 属性指示 CasAuthenticationFilter 尝试验证所有工件,而不是仅验证 filterProcessesUrl 上存在的工件。ServiceAuthenticationDetailsSource 创建一个 ServiceAuthenticationDetails,以确保在验证票证时使用基于 HttpServletRequest 的当前 URL 作为服务 URL。可以通过注入返回自定义 ServiceAuthenticationDetails 的自定义 AuthenticationDetailsSource 来自定义生成服务 URL 的方法。

<bean id="casFilter"
	class="org.springframework.security.cas.web.CasAuthenticationFilter">
...
<property name="serviceProperties" ref="serviceProperties"/>
<property name="authenticationDetailsSource">
	<bean class=
	"org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource">
	<constructor-arg ref="serviceProperties"/>
	</bean>
</property>
</bean>

您还需要更新 CasAuthenticationProvider 来处理代理票证。为此,将 Cas20ServiceTicketValidator 替换为 Cas20ProxyTicketValidator。您需要配置 statelessTicketCache 以及要接受哪些代理。您可以在下面找到接受所有代理所需的更新示例。

<bean id="casAuthenticationProvider"
	class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
...
<property name="ticketValidator">
	<bean class="org.apereo.cas.client.validation.Cas20ProxyTicketValidator">
	<constructor-arg value="https://localhost:9443/cas"/>
	<property name="acceptAnyProxy" value="true"/>
	</bean>
</property>
<property name="statelessTicketCache">
	<bean class="org.springframework.security.cas.authentication.EhCacheBasedTicketCache">
	<property name="cache">
		<bean class="net.sf.ehcache.Cache"
			init-method="initialise" destroy-method="dispose">
		<constructor-arg value="casTickets"/>
		<constructor-arg value="50"/>
		<constructor-arg value="true"/>
		<constructor-arg value="false"/>
		<constructor-arg value="3600"/>
		<constructor-arg value="900"/>
		</bean>
	</property>
	</bean>
</property>
</bean>

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

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

相关文章

详细解释下flutter初始示例的代码

详细解释下flutter初始示例的代码 main 首句导入需要的包 类似于其他语言的import main函数为入口函数 包裹MyApp类 MyApp 这个类继承自无状态类 可见myapp不管理任何状态 build方法是所有widget内必须实现的方法 此处返回一个 ChangeNotferiProvider 可以看到它用于管理应…

理解 REST API 和 GraphQL 的区别

你可能听说过 GraphQL&#xff0c;但对它与 REST 的区别还不完全确定。今天我们将介绍 REST 和 GraphQL 的一些基本原理&#xff0c;以及它们的不同使用场景。 GraphQL 作为 REST API 的替代品越来越受欢迎&#xff0c;不过它不一定是完全的“替代品”。 根据你的使用情景&am…

LLM笔记:训练大模型之并行化

1 数据并行 最常见的并行化手段主要是把数据分成多个块&#xff0c;然后每个节点就可以在本地独立的跑各自的数据任务&#xff0c;最后再和其他节点通信&#xff0c;进而汇总最后的结果好处就是计算效率高&#xff0c;每个节点可以独自计算自己的任务且这种方法易于实现缺点就…

【Python基础篇】一篇文章入门Python,进入Python的世界

文章目录 0.前言1.打印&#xff08;Hello&#xff0c;World&#xff09;2.创建变量3.打印升级3.1 打印一句话中间加变量3.2 sep设置分隔符3.3 end和换行 4. 注释 0.前言 大家好&#xff0c;我是小辰&#xff0c;前几天做了个重大的决定&#xff0c;学习python。 首先&#xff0…

博途S7-1500PLC“虚轴“编程应用

1、CODESYS如何添加虚轴 如何添加虚轴(AM400PLC)-CSDN博客文章浏览阅读164次。EtherCAT运动控制总线启用的时候,选择EtherCAT总线任务周期。选择好后,选择点击添加。https://rxxw-control.blog.csdn.net/article/details/139898985虚轴是利用软件算法实现的运动控制轨迹规划…

外挂级OCR神器:免费文档解析、表格识别、手写识别、古籍识别、PDF转Word

智能文档解析&#xff1a;大模型友好的文档解析工具 PDF转Markdown 支持将任意格式的文件&#xff08;图片、PDF、Doc&#xff0f;Docx、网页等&#xff09;解析为Markdown或Json格式&#xff0c;以对LLM友好的方式呈现。 更高速度&#xff1a;100页PDF最快1.5s完成解析 更大…

DEBOPIE框架:打造最好的ChatGPT交易机器人

本文介绍了如何利用 DEBOPIE 框架并基于 ChatGPT 创建高效交易机器人&#xff0c;并强调了在使用 AI 辅助交易时需要注意的限制以及操作步骤。原文: Build the Best ChatGPT Trading Bots with my “DEBOPIE” Framework 如今有大量文章介绍如何通过 ChatGPT 帮助决定如何以及在…

Hi3861 OpenHarmony嵌入式应用入门--TCP Server

本篇使用的是lwip编写tcp服务端。需要提前准备好一个PARAM_HOTSPOT_SSID宏定义的热点&#xff0c;并且密码为PARAM_HOTSPOT_PSK LwIP简介 LwIP是什么&#xff1f; A Lightweight TCP/IP stack 一个轻量级的TCP/IP协议栈 详细介绍请参考LwIP项目官网&#xff1a;lwIP - A Li…

6.7、函数的分文件编写

mian函数部分代码 #include <iostream> using namespace std; #include <string> #include "swap.h"//函数的分文件编写 //实现两个数字进行交换的函数//函数的声明 //void swap(int a,int b); //函数的定义 //void swap(int a, int b) //{ // int temp…

9. Revit API UI: UIView、UIDocument、框选聚焦

9. Revit API UI: UIView、UIDocument、框选聚焦 UI命名空间下的API&#xff0c;到这里差不多就要讲完了&#xff0c;同Application那篇所讲的几个类与接口&#xff0c;都是带UI的对应了一个不带UI的&#xff0c;如UIApplication和Application&#xff0c;作用呢&#xff0c;也…

Python基于PyQt5和卷积神经网络分类模型(CNN分类算法)实现时装类别识别系统GUI界面项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 随着深度学习技术的发展&#xff0c;计算机视觉领域取得了显著的进步&#xff0c;特别是在图像分类、目…

Java8环境安装(jdk1.8安装)详细教程

Java 8环境安装&#xff08;jdk1.8安装&#xff09;详细教程 Java 8&#xff08;也称为JDK 1.8&#xff09;&#xff0c;是Oracle公司于2014年3月发布的一个重要的Java语言版本。这个版本自发布以来&#xff0c;因其众多的新特性和改进&#xff0c;被认为是Java语言发展历程中…

渗透测试之注入

命令注入 命令注入相关分隔符&#xff1a; 字符说明;仅限Linux环境&#xff0c;用于隔开命令&#xff0c;按顺序执行|前面命令的输出结果作为后面命令的输入内容||前提是前面的命令执行失败&#xff0c;和&&号相反&前后两条命令依次执行&&前提是前面的命…

虚拟机的网络配置

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️ 每一步都向着梦想靠近&#xff0c;坚持就是胜利的序曲 一 …

优化服务,推动企业向前发展

在快速变化的商业环境中&#xff0c;企业的成长离不开优质的服务支持。成都树莓集团&#xff0c;作为数字产业生态链的重要构建者&#xff0c;始终将优化服务、助力企业成长作为自身的核心使命。通过全方位、一站式的服务模式&#xff0c;树莓集团为企业提供强大的支持&#xf…

Idea-Idea配置gitIgnore忽略文件

背景 在项目提交到Git过程中&#xff0c;总有一些文件&#xff0c;例如.idea和.iml等这些我们不想提交的&#xff0c;直接添加进入gitIgnore文件中自动忽略掉。 Idea安装插件 1、在File->Setting->Plugins中搜索gitIgnore并安装插件 2、项目右键new->.ignore File-…

vue实现一个简单的审批绘制功能

1、vue代码 <div class"approval"><div class"approval_ul" v-for"(item,key) in approvalList" :key"key"><div><el-radio-group v-model"item.jointlySign"><el-radio label"1">…

P3374 【模板】树状数组 1

题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; 将某一个数加上 &#x1d465;x 求出某区间每一个数的和 输入格式 第一行包含两个正整数 &#x1d45b;,&#x1d45a;n,m&#xff0c;分别表示该数列数字的个数和操作的总个数。 …

秋招突击——7/2——复习{}——新作{分割等和子集、不同路径、最小路径和、最长回文子串}

文章目录 引言复习新作分割等和子集个人实现参考实现 不同路径个人实现参考实现 最小路径和个人实现参考实现 最长回文子串个人实现参考实现字符串哈希二分 总结 引言 今天起的挺早的&#xff0c;早上把昨天录得关于JVM的相关八股都听完了&#xff0c;然后还背了一部分八股&am…

用Chromatix进行tuning流程

##一、基本调试 ###1、工程初始配置&#xff1a; 这个工具就是一个图形化的参数编辑器&#xff0c;其实所有tuning中的效果参数直接改文件参数酒醒&#xff0c;工具的好处是&#xff1a;带有检查错误和模拟的功能以及一些校验工具和脚本。 初始化可以中需要的配置&#xff1a;t…