1:Cas单点登录原理不做具体介绍了,参考百度推荐文章
2:在开发过程中,客户要求登录使用客户开发的身份统一认证中心,统一身份有cas,oauth2,openid等,这里就简单介绍Cas第三方认证中心,应用调用第三方身份中心,如何获取第三方用户信息,回调返回携带参数等问题,这里以Cas4.2去实现该需求:
下面是一个简单流程:
1):应用发起一个登录请求:
http://localhost:8043/cas/login?service=http://localhost:8002/sgms?center=cas8043
center参数:代表不同的第三方认证中心code,通过数据库表去查询,跳转至第三方身份认证中心地址进行登录
2:第三方认证中心登录成功,跳转至我们自己的身份中心,此时返回携带第三方ST,并且可以获取第三方用户名,我们用第三方账户用户名,在我们cas作一个自动登录流程,向浏览器写入cookie,tgt,跳转至最初我们发起请求的应用,注:第三方cas跳转至我们cas携带参数,需二次跳转,否则我们cas自动登录成功,跳转应用地址属于失败状态
具体表设计:
DROP TABLE IF EXISTS `cas_third_certification_center`;
CREATE TABLE `cas_third_certification_center` (
`id` char(32) NOT NULL,
`code` varchar(64) DEFAULT NULL,
`url` varchar(255) DEFAULT NULL COMMENT '第三方认证中心地址',
`create_id` char(32) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`update_id` char(32) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `cas_third_certification_center` VALUES ('00072e05bf0e4cdaaf1d7d560e11ad11', 'cas8044', 'http://192.168.1.202:8044/cas', null, null, null, null);
INSERT INTO `cas_third_certification_center` VALUES ('00072e05bf0e4cdaaf1d7d560efbad11', 'cas8043', 'http://192.168.1.202:8043/cas', null, null, null, null);
cas8044=》http://192.168.1.202:8044/cas
cas8043=》http://192.168.1.202:8043/cas
查看Cas4.2源码,找到切入点,service检测对应serviceAuthorizationCheck,定义class继承该类,或者重新定义bean,这里我重新定义bean,代码如下:
@Component("serviceAuthorizationCheckOver") public final class ServiceAuthorizationCheckOver extends AbstractAction { private JdbcTemplate jdbcTemplate; private DataSource dataSource; @Autowired(required = false) public void setDataSource(@Qualifier("queryDatabaseDataSource") final DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); this.dataSource = dataSource; } protected final JdbcTemplate getJdbcTemplate() { return this.jdbcTemplate; } protected final DataSource getDataSource() { return this.dataSource; } @NotNull private final ServicesManager servicesManager; private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * Initialize the component with an instance of the services manager. * * @param servicesManager the service registry instance. */ @Autowired public ServiceAuthorizationCheckOver(@Qualifier("servicesManager") final ServicesManager servicesManager) { this.servicesManager = servicesManager; } @Override protected Event doExecute(final RequestContext context) throws Exception { HttpServletRequest request = WebUtils.getHttpServletRequest(context); HttpServletResponse response = WebUtils.getHttpServletResponse(context); // self cas certificate center String requestUrl = request.getRequestURL().toString(); String returnUrlKey = Constants.SERVICE_KEY; String centerCodeKey = Constants.CENTER_CODE_KEY; final Service service = WebUtils.getService(context); context.getFlowScope().put("step", "none"); context.getFlowScope().put("rtnParaStr", ""); if (service == null) { return success(); } HttpSession session = request.getSession(); String secondRedirect = (String) session.getAttribute("centerCode"); // get service's parameter of center Map<String, String> serviceQueryParaMap = UrlCodeUtil.urlSplit(service.getId()); if (serviceQueryParaMap.containsKey(centerCodeKey) && !StringUtils.isEmpty(serviceQueryParaMap.get(centerCodeKey)) && StringUtils.isEmpty(secondRedirect)) { final String centerCode = serviceQueryParaMap.get(centerCodeKey); final String returnUrl = context.getRequestParameters().get(returnUrlKey); CasThirdCertificationCenterDomain thirdCasDO = this.getCertificateInfo(centerCode); String encodeUrlString = UrlCodeUtil.encoderString(requestUrl + "?" + returnUrlKey + "=" + returnUrl.substring(0, returnUrl.lastIndexOf('?'))); String url = thirdCasDO.getUrl() + "?" + returnUrlKey + "=" + encodeUrlString; session.setAttribute("centerCode", centerCode); session.setAttribute("second", false); // set redirect url context.getFlowScope().put("url", url); context.getFlowScope().put("step", "third"); return success(); } if (this.servicesManager.getAllServices().isEmpty()) { final String msg = String.format("No service definitions are found in the service manager. " + "Service [%s] will not be automatically authorized to request authentication.", service.getId()); logger.warn(msg); throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_EMPTY_SVC_MGMR); } // check current service if null or valid final RegisteredService registeredService = this.servicesManager.findServiceBy(service); if (registeredService == null) { final String msg = String.format("Service Management: Unauthorized Service Access. " + "Service [%s] is not found in service registry.", service.getId()); logger.warn(msg); throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, msg); } // service must existed and valid and then second redirect if (context.getRequestParameters().contains(Constants.CAS_TICKET_KEY)) { if (!context.getRequestParameters().contains(returnUrlKey)) { final String msg = "Service key not exist."; logger.warn(msg); throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, msg); } String callBackUrl = request.getRequestURL().toString() + "?service=" + context.getRequestParameters().get(returnUrlKey); String centerCode = (String) session.getAttribute("centerCode"); CasThirdCertificationCenterDomain casDO = this.getCertificateInfo(centerCode); String ticket = context.getRequestParameters().get(Constants.CAS_TICKET_KEY); String username = ""; // get user information from third-party try { TicketValidator ticketValidator = new Cas20ServiceTicketValidator(casDO.getUrl()); Assertion casAssertion = ticketValidator.validate(ticket, callBackUrl); AttributePrincipal casPrincipal = casAssertion.getPrincipal(); username = casPrincipal.getName(); } catch (Exception e) { final String msg = String.format("Get username from [%s] failure", casDO.getUrl()); logger.warn(e.getMessage()); throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, msg); } String url = callBackUrl + "?center" + "=" + session.getAttribute("centerCode"); context.getFlowScope().put("step", "secondRedirect"); session.setAttribute("username", username); context.getFlowScope().put("secondRedirectUrl", url); return success(); } // second redirect to local cas center if (serviceQueryParaMap.containsKey(centerCodeKey) && !StringUtils.isEmpty(serviceQueryParaMap.get(centerCodeKey)) && !StringUtils.isEmpty(secondRedirect)) { String username = (String) session.getAttribute("username"); context.getFlowScope().put("step", "autoSubmit"); context.getFlowScope().put("username", username); session.invalidate(); return success(); } if (!registeredService.getAccessStrategy().isServiceAccessAllowed()) { final String msg = String.format("Service Management: Unauthorized Service Access. " + "Service [%s] is not allowed access via the service registry.", service.getId()); logger.warn(msg); WebUtils.putUnauthorizedRedirectUrlIntoFlowScope(context, registeredService.getAccessStrategy().getUnauthorizedRedirectUrl()); throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, msg); } return success(); } private CasThirdCertificationCenterDomain getCertificateInfo(String centerCode) throws GeneralSecurityException { String searchSqlQuery = "select * from cas_third_certification_center where code = '" + centerCode + "' LIMIT 1"; if (getJdbcTemplate() == null) { throw new GeneralSecurityException("Authentication handler is not configured correctly"); } CasThirdCertificationCenterDomain thirdCasDO = getJdbcTemplate().queryForObject(searchSqlQuery, new CasThirdCertificationCenterRowMapper()); if (thirdCasDO == null) { final String msg = String.format("Third certificate code not correct, can not find third integrated " + "certificate center,the code is [%s].", centerCode); logger.warn(msg); throw new UnauthorizedServiceException(UnauthorizedServiceException.CODE_UNAUTHZ_SERVICE, msg); } return thirdCasDO; } }
login.workflow代码
<?xml version="1.0" encoding="UTF-8"?> <flow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/webflow" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"> <!-- 用来存储用户名和密码信息 --> <var name="credential" class="org.jasig.cas.authentication.UsernamePasswordCredential"/> <on-start> <evaluate expression="initialFlowSetupAction"/> </on-start> <action-state id="ticketGrantingTicketCheck"> <evaluate expression="ticketGrantingTicketCheckAction"/> <transition on="notExists" to="gatewayRequestCheck"/> <transition on="invalid" to="terminateSession"/> <transition on="valid" to="hasServiceCheck"/> </action-state> <action-state id="terminateSession"> <evaluate expression="terminateSessionAction.terminate(flowRequestContext)"/> <transition to="gatewayRequestCheck"/> </action-state> <decision-state id="gatewayRequestCheck"> <if test="requestParameters.gateway != '' and requestParameters.gateway != null and flowScope.service != null" then="gatewayServicesManagementCheck" else="serviceAuthorizationCheck"/> </decision-state> <decision-state id="hasServiceCheck"> <if test="flowScope.service != null" then="renewRequestCheck" else="viewGenericLoginSuccess"/> </decision-state> <decision-state id="renewRequestCheck"> <if test="requestParameters.renew != '' and requestParameters.renew != null" then="serviceAuthorizationCheck" else="generateServiceTicket"/> </decision-state> <!-- Do a service authorization check early without the need to login first --> <action-state id="serviceAuthorizationCheck"> <evaluate expression="serviceAuthorizationCheckOver"/> <transition to="ssoCheck"/> </action-state> <decision-state id="ssoCheck"> <if test="flowScope.step == 'none'" then="initializeLogin"/> <if test="flowScope.step == 'autoSubmit'" then="autoLogin"/> <if test="flowScope.step == 'third'" then="redirectThirdSSO"/> <if test="flowScope.step == 'secondRedirect'" then="secondRedirect"/> </decision-state> <end-state id="redirectThirdSSO" view="externalRedirect:#{flowScope.url}"></end-state> <end-state id="secondRedirect" view="externalRedirect:#{flowScope.secondRedirectUrl}"></end-state> <action-state id="autoLogin"> <evaluate expression="'success'"/> <transition on="success" to="autoLoginNoSubmit"/> <transition on="successWithWarnings" to="showMessages"/> <transition on="authenticationFailure" to="handleAuthenticationFailure"/> <transition on="error" to="initializeLogin"/> </action-state> <action-state id="autoLoginNoSubmit"> <evaluate expression="authenticationViaFormActionOver.autoLoginNoSubmit(flowRequestContext, messageContext, flowScope.username)"/> <transition on="success" to="sendTicketGrantingTicket"/> </action-state> <!-- The "warn" action makes the determination of whether to redirect directly to the requested service or display the "confirmation" page to go back to the server. --> <decision-state id="warn"> <if test="flowScope.warnCookieValue" then="showWarningView" else="redirect"/> </decision-state> <action-state id="initializeLogin"> <evaluate expression="'success'"/> <transition on="success" to="viewLoginForm"/> </action-state> <view-state id="viewLoginForm" view="casLoginView" model="credential"> <binder> <binding property="username" required="true"/> <binding property="password" required="true"/> <!-- <binding property="rememberMe" /> --> </binder> <on-entry> <set name="viewScope.commandName" value="'credential'"/> <!-- <evaluate expression="samlMetadataUIParserAction" /> --> </on-entry> <transition on="submit" bind="true" validate="true" to="realSubmit"/> </view-state> <action-state id="realSubmit"> <evaluate expression="authenticationViaFormAction.submit(flowRequestContext, flowScope.credential, messageContext)"/> <transition on="warn" to="warn"/> <!-- To enable AUP workflows, replace the 'success' transition with the following: <transition on="success" to="acceptableUsagePolicyCheck" /> --> <transition on="success" to="loginSuccess"/> <transition on="successWithWarnings" to="showMessages"/> <transition on="authenticationFailure" to="handleAuthenticationFailure"/> <transition on="error" to="initializeLogin"/> </action-state> <action-state id="loginSuccess"> <evaluate expression="loginSuccessAction"/> <transition on="success" to="sendTicketGrantingTicket"/> </action-state> <view-state id="showMessages" view="casLoginMessageView"> <on-entry> <evaluate expression="sendTicketGrantingTicketAction"/> <set name="requestScope.messages" value="messageContext.allMessages"/> </on-entry> <transition on="proceed" to="serviceCheck"/> </view-state> <action-state id="handleAuthenticationFailure"> <evaluate expression="authenticationExceptionHandler.handle(currentEvent.attributes.error, messageContext)"/> <transition on="AccountDisabledException" to="casAccountDisabledView"/> <transition on="AccountLockedException" to="casAccountLockedView"/> <transition on="AccountPasswordMustChangeException" to="casMustChangePassView"/> <transition on="CredentialExpiredException" to="casExpiredPassView"/> <transition on="InvalidLoginLocationException" to="casBadWorkstationView"/> <transition on="InvalidLoginTimeException" to="casBadHoursView"/> <transition on="FailedLoginException" to="errorCount"/> <transition on="AccountNotFoundException" to="initializeLogin"/> <transition on="UNKNOWN" to="initializeLogin"/> </action-state> <action-state id="errorCount"> <evaluate expression="repeatLoginErrorCountAction"/> <transition on="success" to="initializeLogin"/> </action-state> <action-state id="sendTicketGrantingTicket"> <evaluate expression="sendTicketGrantingTicketAction"/> <transition to="serviceCheck"/> </action-state> <decision-state id="serviceCheck"> <if test="flowScope.service != null" then="generateServiceTicket" else="viewGenericLoginSuccess"/> </decision-state> <action-state id="generateServiceTicket"> <evaluate expression="generateServiceTicketAction"/> <transition on="success" to="warn"/> <transition on="authenticationFailure" to="handleAuthenticationFailure"/> <transition on="error" to="initializeLogin"/> <transition on="gateway" to="gatewayServicesManagementCheck"/> </action-state> <action-state id="gatewayServicesManagementCheck"> <evaluate expression="gatewayServicesManagementCheck"/> <transition on="success" to="redirect"/> </action-state> <action-state id="redirect"> <evaluate expression="flowScope.service.getResponse(requestScope.serviceTicketId)" result-type="org.jasig.cas.authentication.principal.Response" result="requestScope.response"/> <transition to="postRedirectDecision"/> </action-state> <decision-state id="postRedirectDecision"> <if test="requestScope.response.responseType.name() == 'POST'" then="postView" else="redirectView"/> </decision-state> <!-- the "viewGenericLoginSuccess" is the end state for when a user attempts to login without coming directly from a service. They have only initialized their single-sign on session. --> <!-- <end-state id="viewGenericLoginSuccess" view="externalRedirect:#{flowScope.credential.sys_url}" />--> <end-state id="viewGenericLoginSuccess" view="casGenericSuccessView"> <on-entry> <evaluate expression="genericSuccessViewAction.getAuthenticationPrincipal(flowScope.ticketGrantingTicketId)" result="requestScope.principal" result-type="org.jasig.cas.authentication.principal.Principal"/> </on-entry> </end-state> <!-- The "showWarningView" end state is the end state for when the user has requested privacy settings (to be "warned") to be turned on. It delegates to a view defines in default_views.properties that display the "Please click here to go to the service." message. --> <end-state id="showWarningView" view="casConfirmView"/> <!-- Password policy failure states --> <end-state id="abstactPasswordChangeView"> <on-entry> <set name="flowScope.passwordPolicyUrl" value="passwordPolicyConfiguration.passwordPolicyUrl"/> </on-entry> </end-state> <end-state id="casExpiredPassView" view="casExpiredPassView" parent="#abstactPasswordChangeView"/> <end-state id="casMustChangePassView" view="casMustChangePassView" parent="#abstactPasswordChangeView"/> <end-state id="casAccountDisabledView" view="casAccountDisabledView"/> <end-state id="casAccountLockedView" view="casAccountLockedView"/> <end-state id="casBadHoursView" view="casBadHoursView"/> <end-state id="casBadWorkstationView" view="casBadWorkstationView"/> <end-state id="postView" view="postResponseView"> <on-entry> <set name="requestScope.parameters" value="requestScope.response.attributes"/> <set name="requestScope.originalUrl" value="flowScope.service.id"/> </on-entry> </end-state> <!-- The "redirect" end state allows CAS to properly end the workflow while still redirecting the user back to the service required. --> <end-state id="redirectView" view="externalRedirect:#{requestScope.response.url}#{flowScope.rtnParaStr}"/> <end-state id="viewServiceErrorView" view="serviceErrorView"/> <decision-state id="serviceUnauthorizedCheck"> <if test="flowScope.unauthorizedRedirectUrl != null" then="viewRedirectToUnauthorizedUrlView" else="viewServiceErrorView"/> </decision-state> <end-state id="viewRedirectToUnauthorizedUrlView" view="externalRedirect:#{flowScope.unauthorizedRedirectUrl}"/> <end-state id="viewServiceSsoErrorView" view="serviceErrorSsoView"/> <global-transitions> <transition to="viewLoginForm" on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException"/> <transition to="viewServiceErrorView" on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException"/> <transition to="serviceUnauthorizedCheck" on-exception="org.jasig.cas.services.UnauthorizedServiceException"/> <transition to="serviceUnauthorizedCheck" on-exception="org.jasig.cas.services.UnauthorizedServiceForPrincipalException"/> </global-transitions> </flow>
自动登录,绕过数据库验证,生成tgt,重新定义bean,authenticationViaFormAction
@Component("authenticationViaFormActionOver")
public class AuthenticationViaFormActionOver { /** * Authentication succeeded with warnings from authn subsystem that should be displayed to user. */ public static final String SUCCESS_WITH_WARNINGS = "successWithWarnings"; /** * Authentication failure result. */ public static final String AUTHENTICATION_FAILURE = "authenticationFailure"; /** * Flow scope attribute that determines if authn is happening at a public workstation. */ public static final String PUBLIC_WORKSTATION_ATTRIBUTE = "publicWorkstation"; /** * Logger instance. **/ protected final transient Logger logger = LoggerFactory.getLogger(getClass()); /** * Core we delegate to for handling all ticket related tasks. */ @NotNull @Autowired @Qualifier("centralAuthenticationService") private CentralAuthenticationService centralAuthenticationService; @NotNull @Autowired @Qualifier("warnCookieGenerator") private CookieGenerator warnCookieGenerator; @NotNull @Autowired(required = false) @Qualifier("defaultAuthenticationSystemSupport") private AuthenticationSystemSupport authenticationSystemSupport = new DefaultAuthenticationSystemSupport(); public final Event autoLoginNoSubmit(final RequestContext context, final MessageContext messageContext, final String username) { Credential credential = new UsernamePasswordCredential(username, Constants.RANDOM_THIRD_PASSWORD); return createTicketGrantingTicket(context, credential, messageContext); } /** * Is request asking for service ticket? * * @param context the context * @return true, if both service and tgt are found, and the request is not asking to renew. * @since 4.1.0 */ protected boolean isRequestAskingForServiceTicket(final RequestContext context) { final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context); final Service service = WebUtils.getService(context); return (StringUtils.isNotBlank(context.getRequestParameters().get(CasProtocolConstants.PARAMETER_RENEW)) && ticketGrantingTicketId != null && service != null); } /** * Create ticket granting ticket for the given credentials. * Adds all warnings into the message context. * * @param context the context * @param credential the credential * @param messageContext the message context * @return the resulting event. * @since 4.1.0 */ protected Event createTicketGrantingTicket(final RequestContext context, final Credential credential, final MessageContext messageContext) { try { // 获取service final Service service = WebUtils.getService(context); final AuthenticationContextBuilder builder = new DefaultAuthenticationContextBuilder( this.authenticationSystemSupport.getPrincipalElectionStrategy()); //从form表单提交信息封装认证信息 final AuthenticationTransaction transaction = AuthenticationTransaction.wrap(credential); //进行登录的用户登录名和密码的校验 this.authenticationSystemSupport.getAuthenticationTransactionManager().handle(transaction, builder); //通过认证信息和service形成认证结果集 final AuthenticationContext authenticationContext = builder.build(service); //认证成功后进行TGT的创建工作 final TicketGrantingTicket tgt = this.centralAuthenticationService.createTicketGrantingTicket(authenticationContext); WebUtils.putTicketGrantingTicketInScopes(context, tgt); WebUtils.putWarnCookieIfRequestParameterPresent(this.warnCookieGenerator, context); putPublicWorkstationToFlowIfRequestParameterPresent(context); //如果只是进行服务端代码分析,此处不进行警告 if (addWarningMessagesToMessageContextIfNeeded(tgt, messageContext)) { return newEvent(SUCCESS_WITH_WARNINGS); } return newEvent("success"); } catch (final AuthenticationException e) { logger.debug(e.getMessage(), e); return newEvent(AUTHENTICATION_FAILURE, e); } catch (final Exception e) { logger.debug(e.getMessage(), e); return newEvent("error", e); } }
未完待续,需重新整理
相关推荐
本文详细分析了2023年7月抖音平台上美妆品牌「里季、VC美妆、娇润泉」的社媒营销和电商业绩。通过对销售额、直播销售、视频销售、热门商品、粉丝画像等方面的深入剖析,揭示了各品牌在抖音平台的成功之道。里季凭借创始人紫橙董事长的直播带货取得显著成绩,VC美妆则依靠素颜霜爆款和品牌自播,娇润泉通过洁面乳和精华液的推广,借助尾部达人视频切片和头部达人直播实现销售增长。
1、文件说明: Centos8操作系统subscription-manager-rhsm-certificates-1.28.21-3.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf subscription-manager-rhsm-certificates-1.28.21-3.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm
内容概要:本文详细介绍了力士乐驱动调试软件13v16中文版的特点及其在伺服驱动和液压同步调试中的应用。软件具有中文界面,便于理解和操作,涵盖参数设置、监控、诊断和调试四大模块。参数设置模块支持通过输入数值或拖动滑块调整电机速度和加速度;监控模块提供实时数据监测和图表展示;诊断模块帮助排查和解决问题;调试模块适用于高级调试如PID参数调整。此外,文中还分享了多个实用技巧,如批量修改参数、故障代码速查、动态链接库调用等。 适合人群:从事工业自动化、机电一体化领域的工程师和技术人员,尤其是对伺服驱动和液压控制系统有一定经验的人群。 使用场景及目标:①用于伺服驱动系统的调试,确保电机参数正确配置和稳定运行;②用于液压同步控制项目的调试,提高同步精度;③通过丰富的案例和技巧分享,帮助用户高效解决常见问题,提升工作效率。 其他说明:本文不仅介绍了软件的基本功能,还深入探讨了实际调试过程中的一些经验和技巧,为用户提供全面的指导和支持。
计算机绘图-讲稿.pdf
计算机二级access历年真题及讲解.pdf
计算机复习小结.pdf
1、文件说明: Centos8操作系统stubby-0.4.2-2.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf stubby-0.4.2-2.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm
计算机二级C语言历年真题.pdf
内容概要:本文详细介绍了一种利用ELMAN神经网络对红酒数据集进行分类的方法及其MATLAB实现。首先介绍了红酒数据集的特点以及数据预处理步骤,包括数据读取、特征提取、归一化等。接着阐述了ELMAN神经网络的基本概念及其在处理时间序列和模式识别方面的优势。随后展示了如何在MATLAB中创建、配置和训练ELMAN神经网络,包括设置网络结构、选择合适的训练参数等。最后通过评估模型性能,计算分类准确率,并绘制混淆矩阵来展示实验结果。此外还提供了代码优化建议,如调整网络参数、改进数据处理方法等。 适合人群:对机器学习尤其是神经网络感兴趣的初学者,以及有一定MATLAB编程基础的研究人员。 使用场景及目标:适用于想要了解ELMAN神经网络的工作原理及其应用的人群;希望通过具体案例掌握如何使用MATLAB实现神经网络建模和训练的技术人员。 其他说明:文中提供的代码可以直接运行,用户可根据自身需求修改数据源、调整网络参数等,从而应用于不同的分类任务。同时,对于非时序数据也可以考虑采用其他类型的神经网络以提高效率。
数据结构C/C++实现代码,供参考学习,练习,用于面试考试
内容概要:本文详细介绍了Halcon与C#联合开发的一个稳定版本的工业视觉框架。首先强调了环境配置的重要性,确保Halcon的runtime版本与开发环境一致,避免常见的dll版本不匹配问题。接着阐述了图像处理流水线的设计,利用Task+async/await提高效率并避免界面卡顿。文中展示了如何通过状态机实现流程引擎,使配置文件定义处理步骤更加灵活。此外,文章深入探讨了内存管理和异常处理的最佳实践,如使用using语句确保HRegion对象正确释放,以及将Halcon的错误码转化为易读信息。最后,作者分享了一些实用技巧,如通过WCF实现算法和服务化通信,以及提供了一个PCB板检测的Demo项目作为实例。 适合人群:具有一定编程基础,尤其是熟悉C#和Halcon的开发人员,以及从事工业视觉项目的工程师。 使用场景及目标:适用于希望深入了解Halcon与C#联合开发的工业视觉框架的技术人员。主要目标是帮助读者掌握图像处理流程、内存管理、异常处理等方面的知识,从而能够构建高效稳定的工业视觉系统。 其他说明:文中提供了大量代码片段和实践经验,有助于读者更好地理解和应用相关技术。同时,提醒读者在实际开发过程中需要注意的一些常见问题及其解决方案。
计算机二级笔试(选择)真题及答案.pdf
源码
内容概要:本文探讨了在机械模型设计中如何利用技术交底书进行创新。文章首先解释了技术交底书的概念及其重要性,接着通过具体的代码示例展示了如何在机械臂设计中引入动态调整算法以提高性能和效率。此外,文章介绍了如何使用Python和YAML等工具将机械模型的参数化设计与技术交底书相结合,实现了自动化更新和版本控制。最后,文章强调了在设计过程中发现并解决具体问题的重要性,如渐开线参数修形、轨迹预测算法优化以及模块化参数系统的应用。 适合人群:机械工程师、软件开发者、项目经理和技术文档撰写人员。 使用场景及目标:适用于机械模型设计项目的各个阶段,旨在提升设计效率、减少错误率、优化性能,并使技术交底书成为动态且易维护的文档。 其他说明:文中提到的技术手段不仅限于特定行业,可以广泛应用于各种涉及复杂机械系统的工程项目中。同时,文章鼓励跨学科合作,如机械工程与编程的结合,以实现更高效的解决方案。
内容概要:本文详细记录了作者在Cadence平台中完成一个两级放大电路版图设计的过程,涵盖了从初步设计到最终通过LVS(Layout vs Schematic)和DRC(Design Rule Check)验证的所有步骤。文章首先介绍了电路的基本结构和参数设定,如共源放大器和共栅放大器的关键参数调整,以及在Virtuoso环境中进行的具体操作。接着,作者分享了在版图绘制过程中遇到的各种挑战及其解决方案,包括晶体管尺寸优化、走线布局、寄生参数控制、金属层间距调整等。此外,还特别强调了LVS和DRC验证中的常见问题及应对策略,如端口不匹配、器件参数偏差、金属密度规则等。最后,作者总结了一些实用的设计技巧和注意事项,为后续类似项目提供了宝贵的经验。 适合人群:从事集成电路设计的专业人士,尤其是对模拟电路版图设计感兴趣的工程师和技术爱好者。 使用场景及目标:帮助读者掌握Cadence环境下两级放大电路版图设计的方法,提高LVS和DRC验证的成功率,减少设计周期内的返工次数,提升设计效率。 其他说明:文中提到的具体数值和代码片段仅供参考,在实际应用中需要根据具体的工艺规则和个人需求进行适当调整。
内容概要:本文详细介绍了如何利用西门子S7-200 PLC的指针操作来高效地进行数据统计,具体包括求平均值、最大值和最小值的方法。文中提供了完整的代码示例,涵盖了从初始化、循环处理到最终结果输出的全过程。此外,还讨论了指针操作的优势以及一些常见的注意事项,如数据类型的正确处理、防止溢出等。文章强调了指针操作在批量数据处理中的高效性和灵活性,特别是在工控项目中的应用价值。 适合人群:从事工业自动化控制系统的开发人员,尤其是对西门子S7-200 PLC有一定了解的技术人员。 使用场景及目标:适用于需要频繁处理大量数据的工控项目,如温度采集、压力波动分析等。通过掌握本文介绍的方法,开发者能够提高数据处理效率,减少代码复杂度,并确保程序的稳定性和可靠性。 其他说明:文章不仅提供了具体的编程技巧,还分享了许多实践经验,帮助读者更好地理解和应用这些技术。同时提醒读者在实际操作中应注意的一些潜在问题,如数据类型匹配、指针越界等。
1、文件说明: Centos8操作系统subunit-perl-1.4.0-14.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf subunit-perl-1.4.0-14.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm
C++相关书籍,计算机相关书籍,linux相关及http等计算机学习、面试书籍。
无线猫灵5g随身WiFi R106_1.268.4_EQ100 优化更新!