




下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Shiro使用簡(jiǎn)介核心組件SubjectSecurityManagerRealms核心組件Subject:即“當(dāng)前操作用戶”SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通過(guò)SecurityManager來(lái)管理內(nèi)部組件實(shí)例,并通過(guò)它來(lái)提供安全管理的各種服務(wù)Realm充當(dāng)了Shiro與應(yīng)用安全數(shù)據(jù)間的“橋梁”或者“連接器”。也就是說(shuō),當(dāng)對(duì)用戶執(zhí)行認(rèn)證(登錄)和授權(quán)(訪問(wèn)控制)驗(yàn)證時(shí),Shiro會(huì)從應(yīng)用配置的Realm中查找用戶及其權(quán)限信息Shiro完整架構(gòu)圖
其他主要組件Authenticator:認(rèn)證,核實(shí)用戶身份Authorizer:授權(quán),訪問(wèn)控制SessionManager:CacheManager:對(duì)Shiro的其他組件提供緩存支持Shiro認(rèn)證過(guò)程
Shiro認(rèn)證過(guò)程1、應(yīng)用程序構(gòu)建了一個(gè)終端用戶認(rèn)證信息的AuthenticationToken實(shí)例后,調(diào)用Subject.login方法。
2、Sbuject的實(shí)例通常是DelegatingSubject類(或子類)的實(shí)例對(duì)象,在認(rèn)證開(kāi)始時(shí),會(huì)委托應(yīng)用程序設(shè)置的securityManager實(shí)例調(diào)用securityManager.login(token)方法。
3、SecurityManager接受到token(令牌)信息后會(huì)委托內(nèi)置的Authenticator的實(shí)例(通常都是ModularRealmAuthenticator類的實(shí)例)調(diào)用authenticator.authenticate(token).ModularRealmAuthenticator在認(rèn)證過(guò)程中會(huì)對(duì)設(shè)置的一個(gè)或多個(gè)Realm實(shí)例進(jìn)行適配,它實(shí)際上為Shiro提供了一個(gè)可拔插的認(rèn)證機(jī)制。
Shiro認(rèn)證過(guò)程4、如果在應(yīng)用程序中配置了多個(gè)Realm,ModularRealmAuthenticator會(huì)根據(jù)配置的AuthenticationStrategy(認(rèn)證策略)來(lái)進(jìn)行多Realm的認(rèn)證過(guò)程。在Realm被調(diào)用后,AuthenticationStrategy將對(duì)每一個(gè)Realm的結(jié)果作出響應(yīng)。
注:如果應(yīng)用程序中僅配置了一個(gè)Realm,Realm將被直接調(diào)用而無(wú)需再配置認(rèn)證策略。
5、判斷每一個(gè)Realm是否支持提交的token,如果支持,Realm將調(diào)用getAuthenticationInfo(token);getAuthenticationInfo方法就是實(shí)際認(rèn)證處理,我們通過(guò)覆蓋Realm的doGetAuthenticationInfo方法來(lái)編寫我們自定義的認(rèn)證處理。認(rèn)證代碼Subjectmyadmin=SecurityUtils.getSubject();if(!myadmin.isAuthenticated()){ UsernamePasswordTokentoken=new UsernamePasswordToken(account,password); token.setRememberMe(true);try{ myadmin.login(token);}catch(UnknownAccountExceptionuae){ message="用戶名不正確";return
ERROR;}認(rèn)證代碼catch(IncorrectCredentialsExceptionice){ message="密碼錯(cuò)誤"; return
ERROR;}catch(LockedAccountExceptionlae){ message="用戶被鎖"; return
ERROR;}catch(ExcessiveAttemptsExceptioneae){ message="用戶名或密碼錯(cuò)誤"; return
ERROR;}catch(AuthenticationExceptionae){ message="用戶名或密碼錯(cuò)誤"; return
ERROR;}}currentUser.logout();//退出代碼Shiro授權(quán)授權(quán)有著三個(gè)核心元素:權(quán)限、角色和用戶。權(quán)限Shiro權(quán)限聲明通常是使用以冒號(hào)分隔的表達(dá)式。下面以實(shí)例來(lái)說(shuō)明權(quán)限表達(dá)式。
可查詢用戶數(shù)據(jù)
User:view
可查詢或編輯用戶數(shù)據(jù)
User:view,edit
可對(duì)用戶數(shù)據(jù)進(jìn)行所有操作
User:*或User
可編輯id為123的用戶數(shù)據(jù)
User:edit:123
角色
Shiro支持兩種角色模式:
1、傳統(tǒng)角色:一個(gè)角色代表著一系列的操作,當(dāng)需要對(duì)某一操作進(jìn)行授權(quán)驗(yàn)證時(shí),只需判斷是否是該角色即可。這種角色權(quán)限相對(duì)簡(jiǎn)單、模糊,不利于擴(kuò)展。
2、權(quán)限角色:一個(gè)角色擁有一個(gè)權(quán)限的集合。授權(quán)驗(yàn)證時(shí),需要判斷當(dāng)前角色是否擁有該權(quán)限。這種角色權(quán)限可以對(duì)該角色進(jìn)行詳細(xì)的權(quán)限描述,適合更復(fù)雜的權(quán)限設(shè)計(jì)。
授權(quán)實(shí)現(xiàn)Shiro支持三種方式實(shí)現(xiàn)授權(quán)過(guò)程:1編碼實(shí)現(xiàn)2注解實(shí)現(xiàn)3JSPTaglig實(shí)現(xiàn)Shiro授權(quán)的內(nèi)部處理機(jī)制
授權(quán)流程1、在應(yīng)用程序中調(diào)用授權(quán)驗(yàn)證方法(Subject的isPermitted*或hasRole*等)
2、Sbuject的實(shí)例通常是DelegatingSubject類(或子類)的實(shí)例對(duì)象,在認(rèn)證開(kāi)始時(shí),會(huì)委托應(yīng)用程序設(shè)置的securityManager實(shí)例調(diào)用相應(yīng)的isPermitted*或hasRole*方法。
3、接下來(lái)SecurityManager會(huì)委托內(nèi)置的Authorizer的實(shí)例(默認(rèn)是ModularRealmAuthorizer類的實(shí)例,類似認(rèn)證實(shí)例,它同樣支持一個(gè)或多個(gè)Realm實(shí)例認(rèn)證)調(diào)用相應(yīng)的授權(quán)方法。
4、每一個(gè)Realm將檢查是否實(shí)現(xiàn)了相同的Authorizer接口。然后,將調(diào)用Reaml自己的相應(yīng)的授權(quán)驗(yàn)證方法。
。
授權(quán)流程當(dāng)使用多個(gè)Realm時(shí),不同于認(rèn)證策略處理方式,授權(quán)處理過(guò)程中:
1、當(dāng)調(diào)用Realm出現(xiàn)異常時(shí),將立即拋出異常,結(jié)束授權(quán)驗(yàn)證。
2、只要有一個(gè)Realm驗(yàn)證成功,那么將認(rèn)為授權(quán)成功,立即返回,結(jié)束認(rèn)證Shiro有3中認(rèn)證策略的具體實(shí)現(xiàn):
AtLeastOneSuccessfulStrategy只要有一個(gè)(或更多)的Realm驗(yàn)證成功,那么認(rèn)證將被視為成功FirstSuccessfulStrategy第一個(gè)Realm驗(yàn)證成功,整體認(rèn)證將被視為成功,且后續(xù)Realm將被忽略AllSuccessfulStrategy所有Realm成功,認(rèn)證才視為成功基于傳統(tǒng)角色授權(quán)實(shí)現(xiàn)
SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.hasRole("administrator")){}else{}相關(guān)驗(yàn)證方法1.hasRole(StringroleName)當(dāng)用戶擁有指定角色時(shí),返回true2.hasRoles(List<String>roleNames)按照列表順序返回相應(yīng)的一個(gè)boolean值數(shù)組3.hasAllRoles(Collection<String>roleNames)如果用戶擁有所有指定角色時(shí),返回true斷言支持
Shiro還支持以斷言的方式進(jìn)行授權(quán)驗(yàn)證。斷言成功,不返回任何值,程序繼續(xù)執(zhí)行;斷言失敗時(shí),將拋出異常信息。使用斷言,可以使我們的代碼更加簡(jiǎn)潔。SubjectcurrentUser=SecurityUtils.getSubject();currentUser.checkRole("bankTeller");openBankAccount();斷言的相關(guān)方法Subject方法描述checkRole(StringroleName)斷言用戶是否擁有指定角色checkRoles(Collection<String>roleNames)斷言用戶是否擁有所有指定角色checkRoles(String...roleNames)對(duì)上一方法的方法重載基于權(quán)限角色授權(quán)實(shí)現(xiàn)
相比傳統(tǒng)角色模式,基于權(quán)限的角色模式耦合性要更低些,它不會(huì)因角色的改變而對(duì)源代碼進(jìn)行修改,因此,基于權(quán)限的角色模式是更好的訪問(wèn)控制方式。
它的代碼實(shí)現(xiàn)有以下幾種實(shí)現(xiàn)方式:基于權(quán)限對(duì)象的實(shí)現(xiàn)PermissionprintPermission=newPrinterPermission("laserjet4400n","print");SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted(printPermission)){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}PermissionprintPermission=newPrinterPermission("laserjet4400n","print");SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted(printPermission)){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}相關(guān)方法1.isPermitted(Permissionp)Subject擁有制定權(quán)限時(shí),返回treu2.isPermitted(List<Permission>perms)返回對(duì)應(yīng)權(quán)限的boolean數(shù)組3.isPermittedAll(Collection<Permission>perms)Subject擁有所有制定權(quán)限時(shí),返回true基于字符串的實(shí)現(xiàn)
SubjectcurrentUser=SecurityUtils.getSubject();if(currentUser.isPermitted("printer:print:laserjet4400n")){//showthePrintbutton}else{//don'tshowthebutton?Greyitout?}斷言實(shí)現(xiàn)
SubjectcurrentUser=SecurityUtils.getSubject();Permissionp=newAccountPermission("open");currentUser.checkPermission(p);openBankAccount();SubjectcurrentUser=SecurityUtils.getSubject();currentUser.checkPermission("account:open");openBankAccount();斷言實(shí)現(xiàn)的相關(guān)方法1.checkPermission(Permissionp)斷言用戶是否擁有制定權(quán)限2.checkPermission(Stringperm)斷言用戶是否擁有制定權(quán)限3.checkPermissions(Collection<Permission>perms)斷言用戶是否擁有所有指定權(quán)限4.checkPermissions(String...perms)斷言用戶是否擁有所有指定權(quán)限基于注解的授權(quán)實(shí)現(xiàn)
@RequiresAuthentication
@RequiresGuest@RequiresPermissions("account:create")@RequiresRoles
@RequiresUser
基于JSPTAG的授權(quán)實(shí)現(xiàn)
<%@taglibprefix="shiro"uri=""%><shiro:guest></shiro:guest><shiro:authenticated></shiro:authenticated><shiro:notAuthenticated></shiro:notAuthenticated>Hello,<shiro:principal/>,howareyoutoday?<shiro:hasRolename="administrator"></shiro:hasRole><shiro:lacksRolename="administrator"></shiro:lacksRole><shiro:hasAnyRolesname="developer,projectmanager,administrator">.</shiro:lacksRole><shiro:hasPermissionname="user:create"></shiro:hasPermission><shiro:lacksPermissionname="user:create"></shiro:lacksPermission>Realm實(shí)現(xiàn)在認(rèn)證、授權(quán)內(nèi)部實(shí)現(xiàn)機(jī)制中都有提到,最終處理都將交給Real進(jìn)行處理。因?yàn)樵赟hiro中,最終是通過(guò)Realm來(lái)獲取應(yīng)用程序中的用戶、角色及權(quán)限信息的。通常情況下,在Realm中會(huì)直接從我們的數(shù)據(jù)源中獲取Shiro需要的驗(yàn)證信息??梢哉f(shuō),Realm是專用于安全框架的DAO.
認(rèn)證實(shí)現(xiàn)
Shiro的認(rèn)證過(guò)程最終會(huì)交由Realm執(zhí)行,這時(shí)會(huì)調(diào)用Realm的getAuthenticationInfo(token)方法。
該方法主要執(zhí)行以下操作:
1、檢查提交的進(jìn)行認(rèn)證的令牌信息
2、根據(jù)令牌信息從數(shù)據(jù)源(通常為數(shù)據(jù)庫(kù))中獲取用戶信息
3、對(duì)用戶信息進(jìn)行匹配驗(yàn)證。
4、驗(yàn)證通過(guò)將返回一個(gè)封裝了用戶信息的AuthenticationInfo實(shí)例。
5、驗(yàn)證失敗則拋出AuthenticationException異常信息。
Realm代碼@OverrideprotectedAuthenticationInfodoGetAuthenticationInfo(AuthenticationTokenauthcToken)throwsAuthenticationException{UsernamePasswordTokentoken=(UsernamePasswordToken)authcToken;Adminuser=(Admin)adminDao.query().is("account",token.getUsername()).result();
if(user!=null){
return
newSimpleAuthenticationInfo(user.getAccount(),user.getPassword(),getName());}else{
return
null;}}授權(quán)實(shí)現(xiàn)
而授權(quán)實(shí)現(xiàn)則與認(rèn)證實(shí)現(xiàn)非常相似,在我們自定義的Realm中,重載doGetAuthorizationInfo()方法,重寫獲取用戶權(quán)限的方法即可。Realm代碼@OverrideprotectedAuthorizationInfodoGetAuthorizationInfo(PrincipalCollectionprincipals){Stringname=getName();Iteratoriterator=principals.fromRealm(name).iterator();StringuserName=null;if(iterator.hasNext()){userName=(String)iterator.next();}Adminuser=(Admin)adminDao.findOne("account",userName);if(user.getRoleSet()!=null){BuguMapper.fetchCascade(user,"roleSet");}
if(user!=null&&user.getRoleSet()!=null){SimpleAuthorizationInfoinfo=newSimpleAuthorizationInfo();
for(Rolegroup:user.getRoleSet()){
info.addRole(group.getName());
if(group.getPerssionSet()!=null){BuguMapper.fetchCascade(group,"perssionSet");
Iteratorit=group.getPerssionSet().iterator();
while(it.hasNext()){info.addStringPermission(((Permission)it.next()).getName());}}
}
returninfo;}else{
return
null;}Shiro配置ApacheShiro的配置主要分為四部分:
對(duì)象和屬性的定義與配置URL的過(guò)濾器配置靜態(tài)用戶配置靜態(tài)角色配置其中,由于用戶、角色一般由后臺(tái)進(jìn)行操作的動(dòng)態(tài)數(shù)據(jù),因此Shiro配置一般僅包含前兩項(xiàng)的配置。
ApacheShiro的大多數(shù)組件是基于POJO的,因此我們可以使用POJO兼容的任何配置機(jī)制進(jìn)行配置,例如:Java代碼、SpingXML、YAML、JSON、ini文件等等。基于spring的配置<beanid="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"><propertyname="realm"ref="myRealm"/><propertyname="sessionMode"value="native"/><propertyname="sessionManager"ref="sessionManager"/></bean><beanid="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"><propertyname="sessionDAO"ref="sessionDAO"/></bean><beanid="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"></bean><beanid="myRealm"class="mons.utils.MongodbRealm"> <propertyname="adminDao"ref="adminDao"></property></bean><beanid="rolesAny"class="mons.context.RolesAnyAuthorizationFilter"></bean>基于spring的配置<beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"><propertyname="securityManager"ref="securityManager"/><propertyname="loginUrl"value="/login/admin_login.jsp"/><propertyname="successUrl"value="/admins/"/><propertyname="unauthorizedUrl"value="/shows/error/no_permission.jsp"/><propertyname="filters"><util:map><entrykey="rolesAny"value-ref="rolesAny"/></util:map></property><propertyname="filterChainDefinitions"><value>/admins/news/indexRebuild**=authc,rolesAny["系統(tǒng)常規(guī)管理,超級(jí)管理員"]/admins/product/indexRebuild**=authc,rolesAny["系統(tǒng)常規(guī)管理,超級(jí)管理員"]/admins/member/indexRebuild**=authc,rolesAny["系統(tǒng)常規(guī)管理,超級(jí)管理員"]</value></property>
</bean>基于ini文件的配置[main]shiro.loginUrl=/login/admin_login.jspauthc.successUrl=/admins/roles.unauthorizedUrl=/shows/error/no_permission.jspperms.unauthorizedUrl=/shows/error/no_permission.jspinirealm=org.apache.shiro.realm.text.IniRealminirealm.resourcePath=classpath:shiro.inimons.utils.MongodbRealmadminDao=cn.eyes.core.admin.AdminDaomyrealm.adminDao=$adminDaosecurityManager.realms=$inirealm,$myrealmsessionManager=org.apache.shiro.web.session.mgt.DefaultWebSessionManagersecurityManager.sessionManager=$sessionManagermons.context.RolesAnyAuthorizationFiltersecurityManager.sessionManager.sessionListeners=$rolesAny[users]admin=1234567,*基于ini文件的配置[roles]admin=*[urls]/admins/news/indexRebuild**=authc,perms[indexrebuild:*]/admins/news/**.jsp=authc,roles[資訊管理],roles[超級(jí)管理員]/admins/news/**=authc,roles[資訊管理],roles[超級(jí)管理員]/admins/survey/**=authc,rolesAny["資訊管理,超級(jí)管理員"]/admins/survey/**.jsp=authc,roles[資訊管理],roles[超級(jí)管理員]/admins/**=authcURL過(guò)濾器配置說(shuō)明URL_Ant_Path_Expression=Path_Specific_Filter_Chain[urls]
/index.html=anon
/user/create=anon
/user/**=authc
/admin/**=authc,roles[administrator]
/rest/**=authc,rest
/remoting/rpc/**=authc,perms["remote:invoke"]
URL表達(dá)式說(shuō)明
1、URL目錄是基于HttpServletRequest.getContextPath()此目錄設(shè)置
2、URL可使用通配符,**代表任意子目錄
3、Shiro驗(yàn)證URL時(shí),URL匹配成功便不再繼續(xù)匹配查找。所以要注意配置文件中的URL順序,尤其在使用通配符時(shí)。
FilterChain定義說(shuō)明
1、一個(gè)URL可以配置多個(gè)Filter,使用逗號(hào)分隔
2、當(dāng)設(shè)置多個(gè)過(guò)濾器時(shí),全部驗(yàn)證通過(guò),才視為通過(guò)
3、部分過(guò)濾器可指定參數(shù),如perms,roles
Shiro內(nèi)置的FilterChain
anonorg.apache.shiro.web.filter.authc.AnonymousFilterauthcorg.apache.shiro.web.filter.authc.FormAuthenticationFilterauthcBasicorg.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilterpermsorg.apache.shiro.web.filter.authz.PermissionsAuthorizationFilterportorg.apache.shiro.web.filter.authz.PortFilterrestorg.apache.shiro.web.filter.authz.HttpMethodPermissionFilterrolesorg.apache.shiro.web.filter.authz.RolesAuthorizationFiltersslorg.apache.shiro.web.filter.authz.SslFilteruserorg.apache.shiro.web.filter.authc.UserFilter內(nèi)置過(guò)濾器詳解rest:例如/admins/user/**=authc,rest[user]根據(jù)請(qǐng)求的方法,想當(dāng)與/admins/user/**=authc,perms[user:method]port:例如/admins/user/**=authc,prot[8081]當(dāng)請(qǐng)求的rul端口不是8081時(shí),跳轉(zhuǎn)到
perms:例如/admins/user/**=authc,perms[“user:add:*”]內(nèi)置過(guò)濾器詳解prems參數(shù)可以寫多個(gè),當(dāng)寫多個(gè)時(shí)要加上雙引號(hào),并且參數(shù)之間用逗號(hào)分割roles例如/admins/user/**=authc,roles[admin]參數(shù)可以寫多個(gè),當(dāng)寫多個(gè)時(shí)要加上雙引號(hào),并且參數(shù)之間用逗號(hào)分割anon例如/admins/**=anon沒(méi)有參數(shù),表示可以匿名使用內(nèi)置過(guò)濾器詳解authc:例如/admins/user/**=authc
表示需要認(rèn)證才能使用,沒(méi)有參數(shù)authcBasic:例如/admins/user/**=authcBasic沒(méi)有參數(shù),表示httpBasic認(rèn)證,沒(méi)有參數(shù)ssl:例如/admins/user/**=ssl沒(méi)有參數(shù),表示安全url請(qǐng)求,httpsuser:例如/admins/user/**=user沒(méi)有參數(shù),表示存在用戶,當(dāng)?shù)侨氩僮鲿r(shí)不做檢查會(huì)話管理可在任何應(yīng)用或架構(gòu)層一致地使用SessionAPI.那些希望使用會(huì)話的應(yīng)用開(kāi)發(fā)者,不必被迫使用Servlet或EJB容器了?;蛘撸绻谑褂眠@些容器,開(kāi)發(fā)者現(xiàn)在也可以選擇使用在任何層統(tǒng)一一致的會(huì)話API,取代Servlet或EJB機(jī)制。
代碼Sessionsession=subject.getSession();Sessionsession=subject.getSession(booleancreate);session.setAttribute("key",someValue);session.getAttribute(“key”)Datetimestamp=session.getLastAccessTime();session.setTimeout(millis);
加密<beanid="md5Matcher"class="org.apache.shiro.authc.credential.Md5CredentialsMatcher"></bean>
<beanid="myRealm"cl
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年第六屆全國(guó)國(guó)家版圖知識(shí)競(jìng)賽試題題庫(kù)(中小學(xué)組)附參考答案詳解【模擬題】
- 基于注意力機(jī)制的語(yǔ)音腦電信號(hào)解碼研究
- 2025年醫(yī)療資源區(qū)域合作與共享機(jī)制研究及政策建議報(bào)告
- 2025年康復(fù)醫(yī)療服務(wù)體系康復(fù)康復(fù)與康復(fù)康復(fù)服務(wù)商業(yè)模式創(chuàng)新分析預(yù)測(cè)策略研究報(bào)告
- 數(shù)字化教材在基礎(chǔ)教育階段的開(kāi)發(fā)與應(yīng)用2025年調(diào)研與分析報(bào)告
- 政策支持下的2025年醫(yī)療機(jī)構(gòu)信息化建設(shè)與醫(yī)療信息化產(chǎn)業(yè)創(chuàng)新研究報(bào)告
- 2025年農(nóng)業(yè)科技創(chuàng)新項(xiàng)目資金申請(qǐng)報(bào)告:精準(zhǔn)施肥技術(shù)篇
- 2025年醫(yī)藥電商平臺(tái)醫(yī)藥電商藥品銷售渠道合規(guī)管理專家建議專家分析報(bào)告
- 2025年海上風(fēng)力發(fā)電場(chǎng)運(yùn)維團(tuán)隊(duì)培訓(xùn)與發(fā)展研究報(bào)告
- 3D打印古跡復(fù)原展示區(qū)行業(yè)跨境出海項(xiàng)目商業(yè)計(jì)劃書(shū)
- 【MOOC】大學(xué)物理-力學(xué)、電磁學(xué)-重慶大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 擋土墻施工圖設(shè)計(jì)說(shuō)明(完整版)
- 面試官認(rèn)證培訓(xùn)
- 【課件】科技與文化-決定建筑形式+課件高中美術(shù)人教版(2019)選擇性必修4+設(shè)計(jì)
- 診所藥品自查報(bào)告
- 2024年保安員證考試題庫(kù)及答案(共240題)
- 智能化工程投標(biāo)書(shū)
- 恒牙臨床解剖-上頜中切牙(牙體解剖學(xué)課件)
- 【招投標(biāo)管理探究的國(guó)內(nèi)外文獻(xiàn)綜述2600字】
- (新版)軍隊(duì)文職人員招聘(軍需保管員)強(qiáng)化練習(xí)復(fù)習(xí)題庫(kù)(含答案)
- 傳感器技術(shù)-武漢大學(xué)
評(píng)論
0/150
提交評(píng)論