基于SAML单点登录实现方案的分析.doc_第1页
基于SAML单点登录实现方案的分析.doc_第2页
基于SAML单点登录实现方案的分析.doc_第3页
基于SAML单点登录实现方案的分析.doc_第4页
基于SAML单点登录实现方案的分析.doc_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于SAML单点登录实现方案的分析 摘要随着信息技术和网络技术的迅猛发展,客户在信息化的过程中拥有了多套不同厂商开发的应用系统。这些系统互相独立,用户在使用每个应用系统之前 都必须按照相应的系统身份进行登录,为此用户必须记住每一个系统的用户名和密码,这给用户带来了不少麻烦。特别是随着系统的增多,出错的可能性就会增加, 受到非法截获和破坏的可能性也会增大,安全性就会相应降低。针对于这种情况,单点登录概念应运而生,同时不断地被应用到企业应用系统中。本文对单 点登录SSO(Single Sign-On)的背景进行了分析,介绍了两种常见的单点登录技术,重点介绍了SAML技术及其实现单点登录的两种方式。本文基于SAML技术设计了一套 可行的方案,并对实现代码进行了必要的分析。最后对安全性进行了分析,给出了相应的解决方法。关键词单点登录,SAML,断言Analysis based on the case of accomplishment of SAMLs single sign-onWang Shifeng( College Of Software Technology)Directed by Professor Chen DerenAbstractDuring the process of informationization, customers always use several variously application system provided by different firms. So customers must remember every account and password for different systems if they want to log in or use these systems, as all of them are operating independently from each other. It brings a lot of troubles to the custormers. Especially, if more systems they are using, it is more likely for them to make mistakes, also get illegal campture and destruct, then lower the security of the account. Aimed at fix this problem, the single sign-on come into being and is applied to the company application system grandually.This paper analyses the background of SSO(Single Sign-On) problem and introduces two common techniques of SSO, emphasizes SAML technique and two methods of SSO. And has designed a feasible SSO system grounded on SAML technique, meanwhile made a analysis of the security and give the relevant solution.KeywordsSingle Sign-on, SAML, Assertion目录第一章 绪论 71.1 本文研究的背景 71.2本文研究的意义 8第二章 单点登录的技术基础 122.1 单点登录的概念 122.2 国内外的研究概况 122.3 SAML简介 132.3.1 Browser/Artifact方式 152.3.2 Browser/POST方式 16第三章 单点登录方案的设计和实现 173.1 设计思路 173.1.1 用户登录流程 183.2 IDP的设计 193.3 SP过滤器的设计 533.4 安全性分析 663.5 系统实现界面 66参考文献 70致谢 70第一章 绪论1.1 本文研究的背景在 大多数计算机连入网络之前,各个系统中像身份验证和授权这类安全服务的实现完全是独立的。因此,执行身份验证所需的全部代码,以及密钥、口令,供授权决策 所用的用户信息,以及授权策略本身均存放于使用这些信息的系统上。最初,系统连接到网络上时情况变化不大。每个系统都是一个孤岛,各系统都要求用户拥有一 个帐户才能访问该系统。这种方法有许多明显的缺点。举例来说,设置多个帐户,每个帐户有一个密码、组或其他属性,这对用户和管理员来说非常不方 面。如果一个用户的职责发生变更而修改其帐户属性,或有人离开组织时删除其帐户,管理员要浪费大量时间。如果出现更强大的认证方法,各系统还必须单独地去 升级。随着信息技术和网络技术的迅猛发展,企业的应用网站平台越来越多。比如XX移动,常见的网站就有XX移动门户网站、网上营业厅网站、XX移动动漫门户网站、XX移动梦网网站、XX移 动商城网站、12530彩铃网站等。由于这些系统互相独立,用户在使用每个应用系统之前都必须输入手机号和服务密码进行登录,为此用户必须进入每一个系统 都要重新输入,这给用户带来了不少麻烦。特别是随着系统的增多,出错的可能性就会增加,受到非法截获和破坏的可能性也会增大,安全性就会相应降低。针对于 这种情况,单点登录(Single Sign-on,SSO)概念应运而生。单点登录最初被视为一种提供生产力的奢侈品,而现在已成为一种必需品。当前有越来越多的身份与访问控制管理 (IAM)需求来自Web应用和Web Services,从IDC的市场预测可以看出,年复合增长率CAGR最高的两个子方向之一就是Web单点登录,达到了20.8%。1.2本文研究的意义在XX移 动这样一个企业级的信息系统环境下,随着企业的发展,业务系统的数量在不断的增加,老的系统却不能轻易的替换,这会带来很多的开销。其一是管理上的开销, 需要维护的系统越来越多。很多系统的数据是相互冗余和重复的,数据的不一致性会给管理工作带来很大的压力。业务和业务之间的相关性也越来越大,例如公司的 计费系统和财务系统,财务系统和人事系统之间都不可避免的有着密切的关系。为了降低管理的消耗,最大限度的重用已有投资的系统,很多企业都在进行 着企业应用集成。企业应用集成可以在不同层面上进行:例如在数据存储层面上的“数据大集中”,在传输层面上的“通用数据交换平台”,在应用层面上的“业务 流程整合”,和用户界面上的“通用企业门户”等等。事实上,还用一个层面上的集成变得越来越重要,那就是“身份认证”的整合,也就是“单点登录”。通常来说,每个单独的系统都会有自己的安全体系和身份认证系统。整合以前,进入每个系统都需要进行登录,这样的局面不仅给管理上带来了很大的困难,在安全方面也埋下了重大的隐患:1、每个系统都是独立开发各自的身份认证系统造成资源的浪费,消耗开发成本;2、多个身份认证系统会增加整个系统的管理工作成本;3、用户需要记忆多个帐户和口令,使用极为不便,同时由于用户口令遗忘而导致的支持费用不断上涨;4、无法实现统一认证和授权,多个身份认证系统使安全策略必须逐个在不同的系统内进行设置,因而造成修改策略的进度可能跟不上策略的变化;5、无法统一分析用户的应用行为;因此,对于有多个业务系统应用需求的政府、企业或机构等,需要配置一套统一的身份认证系统,以实现集中统一的身份认证,并减少整个系统的成本。下面是一些著名的调查公司显示的统计数据:用户每天平均 16 分钟花在身份验证任务上 - 资料来源: IDS频繁的 IT 用户平均有 21 个密码 - 资料来源: NTA Monitor Password Survey49% 的人写下了其密码,而 67% 的人很少改变它们每 79 秒出现一起身份被窃事件 - 资料来源:National Small Business Travel Assoc全球欺骗损失每年约 12B - 资料来源:Comm Fraud Control Assoc到 2007 年,身份管理市场将成倍增长至 $4.5B - 资料来源:IDS使用“单点登录”整合后,只需要登录一次就可以进入多个系统,而不需要重新登录,这不仅仅带来了更好的用户体验,更重要的是降低了安全的风险和管理的消耗。请看下面的统计数据:提高 IT 效率:对于每 1000 个受管用户,每用户可节省$70K帮助台呼叫减少至少1/3,对于 10K 员工的公司,每年可以节省每用户 $75,或者合计 $648生产力提高:每个新员工可节省 $1K,每个老员工可节省 $350 ?资料来源:GigaROI 回报:7.5 到 13 个月 ?资料来源:Gartner单 点登录系统的目的就是为这样的应用系统提供集中统一的身份认证,实现“一点登录、多点漫游”的目标,方便用户使用。一个用户如何一次登录,即可使用所有他 可以有权访问的应用系统。我们希望能达到以下效果:登录一次,可使用多个应用系统;统一的身份认证;可配置的身份认证;各个应用系统之间共享用户信息,以 方便系统间数据流转。这里就会存在以下2个关键问题:(1)登录信息如何在多个应用之间传递;(2)各个应用如何检查用户是否已经登录。本文将首先从单点登录的技术基础入手,逐步说明如何解决上述2个问题。第二章 单点登录的技术基础2.1 单点登录的概念单 点登录(SSO,Single Sign-on)是一种方便用户访问多个系统的技术,用户只需在登录时进行一次注册,就可以在多个系统间自由穿梭,不必重复输入用户名和密码来确定身份。 单点登录的实质就是安全上下文(AISSO Context)或凭证(Credential)在多个应用系统之间的传递或共享。当用户登录系统时,客户端软件根据用户的凭证(例如用户名和密码)为用 户建立一个安全上下文,安全上下文包含用于验证用户的安全信息,系统用这个安全上下文和安全策略来判断用户是否具有访问系统资源的权限。图2.1 SSO原理示意图2.2 国内外的研究概况身份认证、单点登录方面常用的技术规范或协议有Kerberos、SAML。Kerberos 协议(RFC 1510)是由MIT开发的一种网络安全应用标准,提供了一种全方位的SSO解决方案。在采用Kerberos的平台中,登录和认证是由操作系统本身维 护;认证凭证也由操作系统保存,操作系统中的各个应用只需要通过配置就能加入到SSO中。Kerberos通过安全的密钥算法,可以做到用户密码不需要直 接在网络中传输,因而传输的信息十分安全。但是搭建一个Kerberos的环境比较复杂,KDC(密钥分发中心)的建立也需要相当多的环节。SAML 为SSO提供了一个安全的协议。SAML是允许Web站点安全地共享身份信息的一个规范,它来自ebXML和其他XML标准背后的国际性联盟OASIS。 站点使用SAML的XML词汇表和请求/应答模式,通过HTTP交换身份信息。这种信息共享标准化能帮助Web站点与多个合作伙伴集成,避免由于为不同合 作伙伴设计和维护各自私有的集成通道而引起的争论。2005年完成的SAML 2.0引入了支持身份联邦(Identity Federation)的一些重要新功能。认证系统设计领域内的进展之一是制定标准化的安全API, 即通用安全服务API(GSS-API)。Austin大学开发的安全网络编程(SNP), 对通用接口进行了进一步的封装, 把界面做到了比GSS-API更高的层次,使同网络安全性有关的编程更加方便了。SUN和微软2005年联合开发并公布了两个技术规范草案:Web Single Sign-On Metadata Exchange (Web SSO MEX) Protocol(Web单点登录元数据交换协议)和Web Single Sign-On Interoperability Profile (Web SSO Interop Profile)(Web单点登录互操作性概览)。这两个技术规范可使Liberty ID-FF和WS-Federation两个安全的域之间实现基于浏览器的Web单点登录。国内目前的进展主要是基于各项技术的整合开发出一些应用型的统一身份认证与权限管理系统。2.3 SAML简介SAML(Security Assertion Markup Language,安全性断言标记语言)是一种基于XML的框架,主要用于在各安全系统之间交换认证、授权和属性信息,它的主要目标之一就是SSO。在 SAML框架下,无论用户使用哪种信任机制,只要满足SAML的接口、信息交互定义和流程规范,相互之间都可以无缝集成。SAML规范的完整框架及有关信 息交互格式与协议使得现有的各种身份鉴别机制(PKI、Kerberos和口令)、各种授权机制(基于属性证书的PMI、ACL、Kerberos的访问 控制)通过使用统一接口实现跨信任域的互操作,便于分布式应用系统的信任和授权的统一管理。 SAML并不是一项新技术。确切地说,它是一种语言,是一种XML描述,目的是允许不同安全系统产生的信息进行交换。SAML规范由以下部分组成: 1. 断言与协议: 定义XML格式的断言的语法语义以及请求和响应协议。2. 绑定与配置文件: 从SAML请求和响应消息到底层通信协议如SOAP或SMTP的映射。 3. 一致性规范: 一致性规范设置了一种基本标准,必须满足这一SAML标准的实现才能够称为一致性实现。这样有助于提高互操作性和兼容性。 4. 安全和保密的问题: SAML体系结构中的安全风险,具体而言就是SAML如何应对这些风险以及无法解决的风险。 SAML应用的实现由三部分组成:(1)主体(Principals),即用户。(2)服务提供者(Service Providers,SP),即各种应用系统。(3)身份提供者(Identity Providers,IDP),即身份认证服务器。很多应用系统服务器可以同时实现SP和IDP功能。SAML的核心为断言(Assertion),断言可传递主体执行的认证信息、属性信息及关于是否允许主体访问其资源的授权决定。针对以上不同目的,SAML提供以下几种不同类型的安全断言:认证断言(Authentication Assertion):认证断言用来声称消息发布者已经认证特定的主体。属性断言(Attribute Assertion):属性断言声称特定主体具有特定的属性。属性可通过URI(统一资源标识)或用来定义结构化属性的一种扩展模式进行详细说明。决定断言(Decision Assertion):一个决定断言报告了一个具体授权请求的结果。授权断言(Authorization Assertion):授权断言声称一个主体被给予访问一个或多个资源的特别许可。SAML断言以XML结构描述且具有嵌套结构,由此一个断言可能包括几个关于认证、授权和属性的不同内在断言(包括认证声明的断言仅仅描述那些先前发生的认证行为)。SAML单点登录主要有两种方式:Browser/Artifact和Browser/POST,其实现流程分别如图2.2和图2.3所示。2.3.1 Browser/Artifact方式图2.2 Browser/Artifact方式 用户登录IDP,或通过SP重定向到IDP的登录界面; 认证通过后,IDP生成一个认证断言,并建立对应的Artifact,然后将此Artifact作为参数返回用户; 用户被重定向到SP; SP根据Artifact查询IDP; IDP根据对应关系将断言返回给SP,并删除断言与Artifact之间的对应关系; SP检查断言,判断用户的身份,如果合法则将主页返回用户。2.3.2 Browser/POST方式图2.3 Browser/POST方式 用户登录IDP,或通过SP重定向到IDP的登录界面; 与Browser/Artifact方式不同,IDP并不生成Artifact,而是直接将断言装入一个自动提交的Form,返回用户; Form被自动提交到SP,其中包含断言; SP根据此断言判断用户的身份,如果合法则将主页返回用户。两种方式各有优 点,Browser/POST方式可减少SP与IDP的交互,节省带宽,而Browser/Artifact方式安全性更高:SP实时查询IDP,可确保 断言的时效性,另外SP查询过Artifact后,IDP即删除Artifact与断言的对应关系,可防止重放攻击。对安全性要求较高的系统而 言,Browser/Artifast更适合。在2005年底,随着监控、移动设备、宽带业务以及应用安全领域的四家主要厂商通过了最后一回合的联邦身份互操作性测试,自由联盟(Liberty Alliance)公布了SAML 2.0。2.4 SAML 2.0工作原理示意图SAML 2.0版在2005年3月刚刚被OASIS批准。Liberty Alliance的目的是让尽可能多的厂商把SAML加入到他们的产品线中。第三章 单点登录方案的设计和实现3.1 设计思路先 来看第一个问题,如何在过个应用系统(SP)之间传递登录信息。在多个应用系统(SP)之间一一建立联系是难以实现的,为此则可以考虑建立一个中心的认证 服务(IDP)。各个应用在检测到未登录之后,转去这个统一的认证服务,确认是否已经登录,并获取登录用户的身份信息。第二个问题,各个应用系统 (SP)如何检查用户是否已经登录。各个Servlet和JSP都是通过URL来提供访问,当用户访问的时候,如果每个Servlet和JSP都去统一认 证服务进行检查,开发的开销非常大。非常幸运的是,在Servlet的规范(版本2.3以上)中提供了一种组织形式Filter,即针对HTTP访问 的过滤器。通过Filter机制,对于每一个应用系统(SP),在一个集中的点进行身份认证的检查即可。整个设计思路如下:首先提供一个集中的中心认证服务器(IDP),通过这个认证服务器来进行用户的身份认证。各个应用系统(SP)在原有实现的基础之上,增加一个Filter来进行是否登录的检测。当 访问某个应用系统(SP)时,Filter首先检查是否已经登录到了当前系统。如果尚未登录,则将请求转向认证服务器(IDP),检查是否已经在中心认证 服务器上登录;如果确认在中心认证服务器(IDP)登录了,则过滤器自动完成登录;如果确认了尚未在中心认证服务器登录,则提示用户输入相应的信息完成登 录即可。中心认证服务器(IDP)可能面对不同的实现要求。认证服务器(IDP)实现可能采用LDAP Server,也可能是关系数据库。这要求认证服务的接口设计提供适应各种认证服务的能力,具备可扩展的结构。3.1.1 用户登录流程用 户登录的流程图如图3.1所示: 用户访问SP; SP检查自身的用户Session,如果Session存在,表明用户已经登录,直接跳转到,否则重定向到IDP的登录界面; IDP提示用户登录; 如果验证成功,IDP即生成用户登录Session,身份认证断言和Artifact,并建立断言与Artifact的对应关系,然后将此 Artifact作为参数向用户发送HTTP重定向指令; 用户被重定向到SP; SP根据此Artifact向IDP发送AuthnRequest请求; IDP查询Artifact与断言的对应表后,用私钥对此断言进行签名,将签名后的断言发送给SP; SP收到断言,先用IDP的公钥验证断言的真实性,然后再查询系统自身的权限检查模块,如果有权访问,则生成用户登录Session,并将系统界面返回给 用户,用户登录成功。图3.1 用户登录流程3.2 IDP的设计IDP采用OpenSAML 开源Java库为基础,在Linux操作系统和Weblogic环境下实现,采用用户管理、身份认证、生成断言和Artifact、签名断言、根据Artifact查询断言的功能。 首先认证服务(IDP)提供一个UserInfo的类,封装了各个应用系统最基本的登录信息。包括了手机号码(billId)、服务密码 (passWord)、用户所在县市编号(countyCode)、当前客户名称(custName)、用户当前套餐编号(planId)、用户当前套餐 名称(planName)、用户所在地市编码(regionCode)、用户当前品牌编号(tradeMark)、用户当前品牌名称 (tradeMarkName)、用户当前状态(userStatus)、用户的UserID(userID)等认证信息。/UserInfo.javapublic class UserInfo implements Serializable private static final long serialVersionUID = 0xf10ee76fb81afe7cL; private long userId; private String custName; private int planId; private String planName; private short tradeMark; private String tradeMarkName; private String regionCode; private String countyCode; private String billId; private short userStatus; private long createTime; private long authId; private String passWord; private String osStatus; public UserInfo() public String getOsStatus() return osStatus; public void setOsStatus(String osStatus) this.osStatus = osStatus; public String getPassWord() return passWord; public void setPassWord(String passWord) this.passWord = passWord; public long getAuthId() return authId; public void setAuthId(long authId) this.authId = authId; public String getBillId() return billId; public void setBillId(String billId) this.billId = billId; public String getCountyCode() return countyCode; public void setCountyCode(String countyCode) this.countyCode = countyCode; public String getPlanName() return planName; public void setPlanName(String planName) this.planName = planName; public String getRegionCode() return regionCode; public void setRegionCode(String regionCode) this.regionCode = regionCode; public short getTradeMark() return tradeMark; public void setTradeMark(short tradeMark) this.tradeMark = tradeMark; public String getTradeMarkName() return tradeMarkName; public void setTradeMarkName(String tradeMarkName) this.tradeMarkName = tradeMarkName; public long getUserId() return userId; public void setUserId(long userId) this.userId = userId; public short getUserStatus() return userStatus; public void setUserStatus(short userStatus) this.userStatus = userStatus; public String getCustName() return custName; public void setCustName(String custName) this.custName = custName; public int getPlanId() return planId; public void setPlanId(int planId) this.planId = planId; public String toString() StringBuffer strBuf = new StringBuffer(); strBuf.append(billid=).append(billId).append(t).append(custName=).append(custName).append(t).append(planId=).append(planId).append(t).append(regionCode=).append(regionCode); return strBuf.toString(); public long getCreateTime() return createTime; public void setCreateTime(long createTime) this.createTime = createTime; IDP根据用户信息生成相应的SAML 断言和Artifact这里的代码来自于opensaml1.1提供的POSTProfileTest.java,用于生成 SAMLResponse并进行签名SAMLResponse r = SAMLPOSTProfile.prepare(,,Collections.singleton(), /生成断言foo,foo,null,,foo,new Date(),Collections.singleton(new SAMLAuthorityBinding(SAMLBinding.SAML_SOAP_HTTPS,,new QName(XML.SAMLP_NS,AttributeQuery);assertNotNull(No SAMLResponse was generated.,r);Iterator i = r.getAssertions();(SAMLAssertion)i.next().sign(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1, /用私钥签名断言ks.getKey(alias,password),Arrays.asList(ks.getCertificateChain(alias);r.sign(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,ks.getKey(alias,password),Arrays.asList(ks.getCertificateChain(alias); AISSOReceive校验IDP生成的Artifact /AISSOReceive.javapublic class AISSOReceive private static final Log logger; private Certificate cert; private String samlMode; private String sessName; private String ssoServer; private int timeOutSecs; static logger = LogFactory.getLog(com.asiainfo.sso.AISSOFilter.class); public String getSessName() return sessName; public AISSOReceive() cert = null; samlMode = AIConf.getStrValue(SAML_MODE); sessName = AIConf.getStrValue(CACHE_NAME); ssoServer = null; timeOutSecs = 0; initCert(); /初始化证书 private void initCert() if(cert != null) return; try CertificateFactory factory = CertificateFactory.getInstance(X.509); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); java.io.InputStream t_InputStream = classLoader.getResourceAsStream(AIConf.getStrValue(KEY_PATH); cert = factory.generateCertificate(t_InputStream); catch(CertificateException e) e.printStackTrace(); /通过Artifact获得断言 private SAMLAssertion receiveByArtifact(String samlEncode, String ipAddr) throws SAMLException, ArtifactParseException, Exception org.opensaml.artifact.SAMLArtifactType0002.Parser parser = new org.opensaml.artifact.SAMLArtifactType0002.Parser(); SAMLArtifactType0002 artifact = (SAMLArtifactType0002)parser.parse(samlEncode); SAMLRequest samlReq = new SAMLRequest(); samlReq.addArtifact(artifact); samlReq.setId(_ + ipAddr + _ + System.currentTimeMillis(); String endpoint = artifact.getSourceLocation().getURI(); SAMLBinding binding = SAMLBindingFactory.getInstance(urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding); SAMLResponse samlResponse = binding.send(endpoint, samlReq); return getAssertion(samlResponse); private SAMLAssertion receiveByBrowser(String samlEncode, String requestUrl) throws NoSuchProviderException, SAMLException, Exception SAMLBrowserProfile profile = SAMLBrowserProfileFactory.getInstance(); org.opensaml.SAMLBrowserProfile.BrowserProfileRequest request = new org.opensaml.SAMLBrowserProfile.BrowserProfileRequest(); request.SAMLResponse = samlEncode; String recipient = HttpUtil.getServerAddrFromUrl(requestUrl); if(logger.isDebugEnabled() logger.debug(recipient: + recipient); org.opensaml.SAMLBrowserProfile.BrowserProfileResponse response = profile.receive(null, request, recipient, ReplayCacheFactory.getInstance(), null, 1); return getAssertion(response.response); private SAMLAssertion getAssertion(SAMLResponse samlResponse) throws SAMLException, Exception if(samlResponse.isSigned() samlResponse.verify(cert); /用IDP的公钥验证签名 else throw new Exception(responseu6CA1u6709u7B7Eu540D!); Iterator iter = samlResponse.getAssertions(); if(iter.hasNext() SAMLAssertion assertion = (SAMLAssertion)iter.next(); if(assertion.isSigned() assertion.verify(cert); return assertion; else throw new Exception(u65ADu8A00u6CA1u6709u7B7Eu540D!); else throw new Exception(u6CA1u6709u65ADu8A00!); public void receive(HttpServletRequest request, String artifact) throws SAMLException, ArtifactParseException, Exception SAMLAssertion assertion = null; if(samlMode != null & samlMode.equals(artifact) assertion = receiveByArtifact(artifact, HttpUtil.getClientIP(request); else assertion = receiveByBrowser(artifact, request.getRequestURL().toString(); setUserInfo(request, assertion); /将信息封装到UserInfo,保存到Session private UserInfo setUserInfo(HttpServletRequest request, SAMLAssertion assertion) throws SAMLException UserInfo userInfo = new UserInfo(); if(ssoServer = null)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论