- 浏览: 433798 次
- 性别:
- 来自: 广州
-
文章分类
最新评论
-
man1900:
想部署及学习了解,可参考本人新的博客获得下载源代码。http: ...
JOffice 中的JBPM4在线流程设计器--初览(Applet版) -
atgoingguoat:
哎。假的。
JOffice 中的JBPM4在线流程设计器--初览(Applet版) -
电竞杀神张无忌:
这是主流程调用子流程报的错大神指导原因吗? ...
JBPM4的子流程与父流程的设计及开发 -
贝塔ZQ:
pageoffice也是office在线编辑的吧,J.Offi ...
J.Office另一种在线Office编辑器整合 -
Mybonnie1:
你好,想问下,串行的多实例任务能做到回退么
Activiti 多个并发子流程的应用
一、Spring Security介绍
Spring Security的前身Acegi,其配置及使用相对来说复杂一些,因为要配置的东西比较多,Sprng Security简化了以前的配置。大家有兴趣可以多多了解以前的版本,因为很多细节在前面的版本可以看得比较清楚,后面的版本需要看源代码才知道其实现的原理了。
基于角色的设计与实现是绝大部分系统中比较常见的权限管理方式,对权限进行分组进行管理有助于减少权限管理的复杂程度。
Spring Security目前提供了三种权限的管理方式:
一、 基于URL的拦截方式
二、 基于方法的AOP拦截方式
三、 基于数据的权限拦截方式
第一种是常见的权限管理方式,第二种有时也可以通过第一种去进行实现,方法级的拦截容易实现,不过要以友好的方式显示权限不足设计及实现就有些啰嗦。基于数据级的安全拦截实现上得更麻烦,在此不作介绍,我们只是针对第一种方式作设计。Spring Security在URL上已经提供了比较好的管理,不过其是以类似以下这种方式进行配置的。
<http auto-config='true'> <intercept-url pattern="/login.jsp*" filters="none"/> <intercept-url pattern="/**" access="ROLE_USER" /> <form-login login-page='/login.jsp'/> </http>
这种要动态实现角色与权限的管理就显得有些不足了,因此需要进行扩展实现,我们可以把一些不需要进行安全拦截的url放在Spring的以上配置中,设置filters=”none”,如images,css,js等,提高访问的速度。
在扩展Spring Security之前,我们需要了解一下Spring Security的相关术语。
Authentication (认证)对象
其实就是一个可以通过Spring Security的认证的身份证明。如实现该接口的类UsernamePasswordAuthenticationToken,表示可以通过username及password作为身份验证。
Authentication对象包含了
- Principal 标识是哪一个对象,可以认为是用户
- Credentials 信任的对象,如密码。
- Authorities 权限的集合,在我们的系统中可以认为是角色的集合 (authorities要赋予给principal的)
SecurityContextHolder
是Spring Security的核心对象,是安全上下文的访问的入口。如取得当前的登录用户可以从该类中的相应的方法取得。该类中包含ThreadLocal私有属性用于存取SecurityContext, SecurityContext包含Authentication私有属性。如实现弹出窗口登录功能的时候,输入的用户名及密码并没有最终经过SPRING SECURITY的filter,那么如何使用得当前用户可以成功登录呢,其就是利用到这一点,通过该类拿到SecurityContext,然后设置一个认证的对象给它,SPRING SECURITY在看到该认证对象的时候,就会成功经过了身份的认证了。
其实也可以这样理解,为了处理Http请求间认证,Spring Security使用HttpSessionIntegrationFilter,HttpSessionIntegrationFilter用于在HttpSession存储Http请求间的SecurityContext。不过我们可以通过SecurityContextHolder去拿到这个SecurityContext
AuthenticationManager
通过Providers 验证 在当前 ContextHolder中的Authentication对象是否合法。
AccessDecissionManager
经过投票机制来审批是否批准操作
Interceptors(拦截器)
拦截器(如FilterSecurityInterceptor,JoinPoint,MethodSecurityInterceptor等)用于协调授权,认证等操作。
Spring Security是Spring中一个强大的安全管理框架,不过目前在我们系统中使用的仅是其中一部分的功能,则权限过滤安全检查的功能。如果抛开这个框架,我们实现权限管理的时候,可能使用最多的方案还是使用Filter来进行过滤,在Filter里判断当前的用户是否为登录用户,若是登录用户,则看是否有权限访问当前的资源,若为未登录用户,则跳至登录页面。
二、扩展Spring Security
扩展Spring Security基于角色的管理策略,通过角色分配,保证系统的安全。其安全的手段包括以下:
1. 登录时需要加上验证码
2. 所有的数据展示及访问页需要登录后才能访问
3. 用户的数据库密码存储时使用Sha-256的加密算法
4. 登录后的所有系统的访问URL均需要授权
5. 登录多少次失败后,可锁定IP,约20分钟后才能自动解锁。(尚未实现)
权限设计目前是采用基于角色控制的方式,用户需要访问系统的资源,首先必须要授予一个角色,而该角色具有访问系统资源的权限的能力,也可以认为是权限的集合。因此,一个用户要访问系统的某个资源(如产品列表),则首先要授予一个能够访问产品列表资源的角色(如productAdmin)。只要任一个用户拥有了该角色,即可以访问该资源。
系统的安全涉及到两个不同的概念,认证和授权。前者是关于确认用户是否确实是他们所宣称的身份。用户进入系统的时候,首先要进行第一个操作就是进行身份认证,即Authentication。在系统中一般表现为用户用账号跟密码登录。如果都正确了,则可以登录系统。在现实中你可以这样理解,员工在进入公司之前,需要进行身份的确认。身份确认通过后,则可以进入公司。进入公司后,并不代表可以随便进入公司的每个办公室。这时就需要每个看当前员工具有哪些角色,即授权。授权则是关于确认用户是否有允许执行一个特定的操作。如当前员工是总经理,则可以进入总经理办公室,并且可以进入普通员工的办公区域。是因为总经理已经授权可以出入这些地方。
在本系统中,权限表现为功能菜单及系统访问的URL。
如:
添加用户,其访问的url为 /system/saveAppUser.do
删除用户,其访问的url为/system/deleteAppUser.do
查询用户,其访问的url为/system/listAppUser.do
因而用户、角色、权限之间的关系可以用如下的图描述:
表设计
一个用户可以有多个角色,每个角色有多个功能菜单,每个功能菜单会对应多个系统访问的URL
表设计如下所示:
表说明:
1. app_user系统用户表,放置系统的所有用户
2. user_role用户角色,放置系统的所有角色
3. app_role角色表,放置用户角色
4. role_fun角色对应的功能表,放置角色拥有的功能
5. app_function系统的功能表,放置系统参与授权的所有功能
6. fun_url系统的功能对应的权限URL表
目前我们需要扩展Spring Security的以下两部分功能
1. 身份认证
2. 授权
Spring Security是由一组的filter来进行统一的过滤,不同的filter进行相应的权限过滤功能。不过在Security跟spring集成的过程中,其是由一个代理的类进行这些filter的统一管理。可以在web.xml中进行了查看,如下所示:
<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/index.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/file-upload</url-pattern> </filter-mapping>
所有经过springSecurityFilterChain的url,都会转到DelegatingFilterProxy类的bean去处理。而该Bean在Spring Security 2.0中,已经内置于安全管理的缺省的配置当中,我们只需要把app-security.xml加入我们系统管理中来即可。如下:
<?xml version="1.0" encoding="UTF-8"?> <b:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:b="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> <http auto-config="true" access-denied-page="/403.jsp" lowercase-comparisons="true" access-decision-manager-ref="accessDecisionManager"> <intercept-url pattern="/images/**" filters="none"/> <intercept-url pattern="/css/**" filters="none"/> <intercept-url pattern="/js/**" filters="none"/> <intercept-url pattern="/403*" filters="none"/> <intercept-url pattern="/404*" filters="none"/> <intercept-url pattern="/500*" filters="none"/> <intercept-url pattern="/ext3/**" filters="none"/> <intercept-url pattern="/fckeditor/**" filters="none"/> <intercept-url pattern="/jsonStruts**" filters="none"/> <form-login default-target-url="/index.jsp" login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" login-processing-url="/j_security_check" /> <logout logout-url="/j_logout.do" logout-success-url="/login.jsp"/> <remember-me key="RememberAppUser"/> </http> <b:bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased"> <b:property name="allowIfAllAbstainDecisions" value="false"/> <b:property name="decisionVoters"> <b:list> <b:bean class="org.springframework.security.vote.RoleVoter"> <b:property name="rolePrefix" value="" /> </b:bean> <b:bean class="org.springframework.security.vote.AuthenticatedVoter" /> </b:list> </b:property> </b:bean> <authentication-manager alias="authenticationManager"/> <authentication-provider user-service-ref="appUserDao"> <password-encoder hash="sha-256" base64="true"/> </authentication-provider> <b:bean id="securityInterceptorFilter" class="com.htsoft.core.web.filter.SecurityInterceptorFilter" > <custom-filter after="FILTER_SECURITY_INTERCEPTOR" /> <b:property name="securityDataSource" ref="securityDataSource"/> </b:bean> <b:bean id="securityDataSource" class="com.htsoft.core.security.SecurityDataSource"> <b:property name="appRoleService" ref="appRoleService"/> <b:property name="anonymousUrls"> <b:set> <b:value>/login.do</b:value> <b:value>/check.do</b:value> </b:set> </b:property> <b:property name="publicUrls"> <b:set> <b:value>/modelsMenu.do</b:value> <b:value>/itemsMenu.do</b:value> <b:value>/file-upload</b:value> <b:value>/index.jsp</b:value> <b:value>/communicate/listPhoneBook.do</b:value> <b:value>/communicate/listPhoneGroup.do</b:value> <b:value>/communicate/moveMail.do</b:value> <b:value>/communicate/listMailFolder.do</b:value> <b:value>/communicate/removeMailFolder.do</b:value> <b:value>/communicate/searchMail.do</b:value> <b:value>/system/getAppUser.do</b:value> <b:value>/system/checkDiary.do</b:value> <b:value>/system/selectDepartment.do</b:value> <b:value>/system/listAppRole.do</b:value> </b:set> </b:property> </b:bean> </b:beans>
身份认证
说明:当用户登录时,会根据用户账号及密码进行验证,验证由authenticationManager来进,其会调用实现UserDetailsService接口实现类完成,在本系统,是由appUserDaoImpl类来实现。
而我们的用户及角色实体要成为安全框架识别的安全实体,需要相应实现不同的接口,如下所示:
访问授权
授权的管理是通过Filter来进行的,用户访问URL时,均需要经过Spring Security的URL进行授权。在本系统中,这个功能是通过SecurityInterceptorFilter来进行。
系统启动时,会把所有的权限以[角色—URL列表]的形式放置在一个全局的Map中,用户访问系统的url时,就会根据当前用户所拥有的角色是否包含此URL。这个全局的权限匹配源则由SecurityDataSource来提供。由于登录用户在进入系统后,都会具备一些常用的功能,所以每个用户均有一个PUBLIC_ROLE的角色,代表可以访问系统的公告资源。该角色对应的可访问的URL,则配置在SecurityDataSource Bean中的publicUrls属性中。
SecurityInterceptorFilter代码如下所示:
package com.htsoft.core.web.filter; /* * 广州宏天软件有限公司 OA办公管理系统 -- http://www.jee-soft.cn * Copyright (C) 2008-2009 GuangZhou HongTian Software Company */ import java.io.IOException; import java.util.HashMap; import java.util.Set; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.security.AccessDeniedException; import org.springframework.security.Authentication; import org.springframework.security.GrantedAuthority; import org.springframework.security.context.SecurityContextHolder; import org.springframework.web.filter.OncePerRequestFilter; import com.htsoft.core.security.SecurityDataSource; /** * 权限拦载器 * @author csx */ public class SecurityInterceptorFilter extends OncePerRequestFilter { /** * 角色权限映射列表源,用于权限的匹配 */ private HashMap<String, Set<String>> roleUrlsMap=null; private SecurityDataSource securityDataSource; public void setSecurityDataSource(SecurityDataSource securityDataSource) { this.securityDataSource = securityDataSource; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { if(logger.isDebugEnabled()){ logger.debug("...enter the SecurityInterceptorFilter doFilterInternal here..."); } String url=request.getRequestURI(); //若有contextPath,则切出来 if(org.springframework.util.StringUtils.hasLength(request.getContextPath())){ String contextPath=request.getContextPath(); int index=url.indexOf(contextPath); if(index!=-1){ url=url.substring(index+contextPath.length()); } } Authentication auth= SecurityContextHolder.getContext().getAuthentication();//取得认证器 boolean isSuperUser=false; for(int i=0;i<auth.getAuthorities().length;i++){ //logger.info("角色名称:"+auth.getAuthorities()[i].getAuthority()); if("超级管理员".equals(auth.getAuthorities()[i].getAuthority())){ isSuperUser=true; } } if(!isSuperUser){//非超级管理员 if(!isUrlGrantedRight(url,auth)){//如果未授权 logger.info("ungranted url:" + url); throw new AccessDeniedException("Access is denied! Url:" + url + " User:" + SecurityContextHolder.getContext().getAuthentication().getName()); } } if(logger.isInfoEnabled()){ logger.info("pass the url:" + url); } //进行下一个Filter chain.doFilter(request, response); } /** * 检查该URL是否授权访问 * @param url * @return */ private boolean isUrlGrantedRight(String url,Authentication auth){ //遍历该用户下所有角色对应的URL,看是否有匹配的 for(GrantedAuthority ga:auth.getAuthorities()){ Set<String> urlSet=roleUrlsMap.get(ga.getAuthority()); //TODO AntPathMatcher here if(urlSet!=null && urlSet.contains(url)){ return true; } } return false; } public void loadDataSource(){ roleUrlsMap=securityDataSource.getDataSource(); } @Override public void afterPropertiesSet() throws ServletException { loadDataSource(); if(roleUrlsMap==null){ throw new RuntimeException("没有进行设置系统的权限匹配数据源"); } } }
三、EXT的扩展实现
至此,我们完成了对Spring Security的权限扩展,但是EXT访问的时候,我们的应用程序都是在一个页面上进行,也就是我们之前说的One Application One Page,几乎所有的请求都是通过Ajax的请求来时行,页面没有刷新,当权限不足的时候,我们如何提示用户呢?另外我们的功能菜单又是如何来根据用户的角色来显示出来呢?在此,我们把需要把角色、功能、权限URL需要进行统一管理。我们从以下几个方面来进行扩展。
当用户权限不足时,我们需要提示用户无限访问该URL,在app-sercurity.xml中,我们配置了以下:
<http auto-config="true" access-denied-page="/403.jsp" lowercase-comparisons="true" access-decision-manager-ref="accessDecisionManager"> <intercept-url pattern="/images/**" filters="none"/> <intercept-url pattern="/css/**" filters="none"/> <intercept-url pattern="/js/**" filters="none"/> <intercept-url pattern="/403*" filters="none"/> <intercept-url pattern="/404*" filters="none"/> <intercept-url pattern="/500*" filters="none"/> <intercept-url pattern="/ext3/**" filters="none"/> <intercept-url pattern="/fckeditor/**" filters="none"/> <intercept-url pattern="/jsonStruts**" filters="none"/> <form-login default-target-url="/index.jsp" login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" login-processing-url="/j_security_check" /> <logout logout-url="/j_logout.do" logout-success-url="/login.jsp"/> <remember-me key="RememberAppUser"/> </http>
即当用户权限不足时,会跳至403页,因此我们可以在此上作文章,当跳至403页时,我们往response的头写一个标识,在ext的connection中获取返回结果时,我们根据这个标识来给用户提示一个友好的信息,如:
403.jsp的代码实现:
<%@ page pageEncoding="UTF-8"%><% response.addHeader("__forbidden","true"); String basePath=request.getContextPath(); %> <html> <head> <title>访问拒绝</title> <style type="text/css"> <!-- .STYLE10 { font-family: "黑体"; font-size: 36px; } --> </style> </head> <body> <table width="510" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td><img src="<%=basePath%>/images/error_top.jpg" width="510" height="80" /></td> </tr> <tr> <td height="200" align="center" valign="top" background="<%=basePath%>/images/error_bg.jpg"> <table width="80%" border="0" cellspacing="0" cellpadding="0"> <tr> <td width="34%" align="right"><img src="<%=basePath%>/images/error.gif" width="128" height="128"></td> <td width="66%" valign="bottom" align="center"> <span class="STYLE10">访问被拒绝</span> <div style="text-align: left;line-height: 22px;"> <font size="2">对不起,您的当前角色没有查看此页面的权限。请联系您的系统管理员,以获得相应的权限。点击这里返回主页。如果需要技术支持,点击这里发送邮件。</font> </div> <a href="#" onclick="javascript:document.location.href='<%=basePath%>/j_logout.do';">重 新 登 录</a> <a href="#" onclick="javascript:history.back(-1);">后 退</a> </td> </table> </td> </tr> <tr> <td><img src="<%=basePath%>/images/error_bootom.jpg" width="510" height="32" /></td> </tr> </table> </body> </html>
处理该标识:
App.init = function() { Ext.util.Observable.observeClass(Ext.data.Connection); Ext.data.Connection.on('requestcomplete', function(conn, resp,options ){ if (resp && resp.getResponseHeader){ if(resp.getResponseHeader('__timeout')) { Ext.ux.Toast.msg('操作提示:','操作已经超时,请重新登录!'); window.location.href=__ctxPath+'/index.jsp?randId=' + parseInt(1000*Math.random()); } if(resp.getResponseHeader('__forbidden')){ Ext.ux.Toast.msg('系统访问权限提示:','你目前没有权限访问:{0}',options.url); } } }); … }
Connection的这个requestcomplete事件是所有的Ajax请求都必须触发的,所以把它作为总的入口。
另外,用户登录后,其功能的菜单如何来配置呢,因此应用程序是通过一个全局的menu.xml文件来进行功能菜单的管理,同时也包括其功能与URL的配置。
<?xml version="1.0" encoding="UTF-8"?> <Menus> <Items id="SystemSetting" text="系统设置" iconCls="menu-system"> ... <Item id="AppRoleView" iconCls="menu-role" text="角色设置"> <Function id="_AppRoleList" text="查看角色" iconCls="menu-list"> <url>/system/listAppRole.do</url> </Function> <Function id="_AppRoleAdd" text="添加角色" iconCls="menu-add"> <url>/system/listAppRole.do</url> <url>/system/saveAppRole.do</url> </Function> <Function id="_AppRoleEdit" text="编辑角色" iconCls="menu-add"> <url>/system/listAppRole.do</url> <url>/system/saveAppRole.do</url> </Function> <Function id="_AppRoleDel" text="删除角色" iconCls="menu-del"> <url>/system/listAppRole.do</url> <url>/system/mulDelAppRole.do</url> </Function> <Function id="_AppRoleGrant" text="授权角色"> <url>/system/listAppRole.do</url> <url>/system/grantAppRole.do</url> </Function> </Item> ... <Item id="ReportTemplateView" iconCls="menu-report" text="报表管理"> ... </Item> </Items> </Menus>
这个XML文件会在应用程序启动添加至系统的全局变量中,以“角色”对应“URL”的Map提供数据源来进行。
那么角色对应的URL是如何来构造的,这个相对简单一些,以上的功能及菜单,其均存在一个Id,如角色设置(AppRoleView),添加角色“_AppRoleAdd”。
每个角色就保存这些ID,所以加载这些ID,就有办法把其下的URL全部加载出来,从而形成角色与URL的映射关系。
另外,我们还可以把用户所拥有的权限,通过该用户拥有哪些角色,每个角色包括哪些权限的ID,从而构造出该用户的权限集合。如下所示,当用户登录后,我们把所有的ID集中放在用户的rights字段中,这样就可以通过ID来决定用户是否有权限访问某个功能按钮,从而达到功能级别的控制,如:
//加载权限 Ext.Ajax.request({ url:__ctxPath+'/system/getCurrentAppUser.do', method:'Get', success:function(response,options){ var object=Ext.util.JSON.decode(response.responseText); //取得当前登录用户的相关信息,包括权限 curUserInfo=new UserInfo(object.user.userId,object.user.fullname,object.user.rights); } });
以下为user.rights的构造,是在用户登录的时候进行配置实现,为AppUserDaoImpl.java的部分代码
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException, DataAccessException { return (UserDetails) getHibernateTemplate().execute( new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { String hql = "from AppUser ap where ap.username=? and ap.delFlag = ?"; Query query = session.createQuery(hql); query.setString(0, username); query.setShort(1, Constants.FLAG_UNDELETED); AppUser user = null; try { user = (AppUser) query.uniqueResult(); if (user != null) { Hibernate.initialize(user.getRoles()); Hibernate.initialize(user.getDepartment()); //进行合并权限的处理 Set<AppRole> roleSet=user.getRoles(); Iterator<AppRole> it=roleSet.iterator(); while(it.hasNext()){ AppRole role=it.next(); if(role.getRoleId().equals(AppRole.SUPER_ROLEID)){//具有超级权限 user.getRights().clear(); user.getRights().add(AppRole.SUPER_RIGHTS); break; }else{ if(StringUtils.isNotEmpty(role.getRights())){ String[]items=role.getRights().split("[,]"); for(int i=0;i<items.length;i++){ if(!user.getRights().contains(items[i])){ user.getRights().add(items[i]); } } } } } } } catch (Exception ex) { logger.warn("user:" + username + " can't not loding rights:" + ex.getMessage()); } return user; } }); }
而其最终的实现效果可以参见我另一篇博客:
http://man1900.iteye.com/blog/517248
发表评论
-
Activiti入门之三--ORM框架MyBatis的基础及使用
2014-05-12 14:29 74641. 概述 上篇我们介绍 ... -
Activiti入门篇之一 Maven环境搭建
2014-04-28 09:09 4488下载地址http://maven.apache.org/d ... -
Activiti 多个并发子流程的应用
2012-08-27 11:29 31875应用场景: 多个部门发起资金计划,最后统一到财务部 ... -
Activiti 工作流会签开发设计思路
2012-07-26 12:12 28526Activiti 工作流会签开 ... -
基于开源流程引擎Activiti5的工作流开发平台
2012-05-17 11:28 7244http://www.redxun.cn:8 ... -
Jbpm4或Activiti5的流程任务分发与汇总
2012-03-20 18:28 6297应用场景:在企业或事业单位,经常需要把一个任务分派给多条线去 ... -
基于标签方式的工作流启动及任务执行开发说明
2011-09-25 21:21 2319基于现在的系统的整 ... -
JOffice2 发布了开源的开发者体验版本啦!
2011-08-09 23:42 7316JOffice的爱好者有福音了,经公司决定,现在发布 ... -
关于JOffice的业务表单与流程的整合问题
2011-07-26 23:55 3334关于 JOffice 的业务表 ... -
利用Spring AOP与JAVA注解为系统增加日志功能
2010-04-20 10:15 17838Spring AOP一直是Spring的一个比较有特色的功能, ... -
Jasper Report与J.Office中的报表开发
2010-01-04 10:32 3778Jasper Report是一个强大 ... -
快速开发平台之---代码加速器
2010-01-02 16:53 8789一、代码加速器的介 ... -
JOffice中的权限管理--功能粒度的权限管理配置
2009-11-14 20:20 9940JOffice中的权限管理是基于角色的管理策略,采用Spr ... -
JOffice中的权限管理--自动登录(remember me)与SHA256加密
2009-11-11 12:39 4212在开发时,可以让系统记住登录,可以避免开发调试重复登录带来的麻 ... -
关于JOffice的权限更新说明--角色权限授予
2009-11-11 12:09 2836JOffice OA 系统的权限是采用基于角色的管理,用户拥有 ... -
Struts,Spring,Hibernate,Ext3完整的应用程序搭建(一)
2009-09-20 12:27 3590最近一直在进行公司产品的研发,工作很辛苦,但收获也颇多,宏天软 ...
相关推荐
DeepSeek与AI幻觉-清华大学团队制作 一、什么是AI幻觉 (定义与基础概念) 二、DeepSeek为什么会产生幻觉 (聚焦特定AI模型的幻觉成因分析) 三、AI幻觉评测 (评估AI幻觉的频率、类型与影响的方法) 四、如何减缓AI幻觉 (解决方案与技术优化方向) 五、AI幻觉的创造力价值 (探讨幻觉在创新场景中的潜在益处,如艺术生成、灵感激发等)
协同过滤算法商品推荐系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 前台用户可以实现注册登录、商品浏览,在线客服,加入购物车,加入收藏,下单购买,个人信息管理,收货信息管理,收藏管理,评论功能。 后台管理员可以进行用户管理、商品分类管理、商品信息管理、订单评价管理、系统管理、订单管理。 【环境需要】 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.数据库:MySql 5.7/8.0等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。
MES系统数字化工厂解决方案.pptx
MUI调用照片以及裁剪和图库照片上传到服务器
GPT付费体验系统最新版系统是一款基于ThinkPHP框架开发的AI问答小程序, 是基于国外很火的ChatGPT进行开发的Ai智能问答小程序。这是一种基于人工智能技术的问答系统, 可以实现智能回答用户提出的问题。相比传统的问答系统,ChatGPT可以更加准确地理解用户的意图, 提供更加精准的答案。同时系统采用了最新的GPT3.5接口与GPT4模型,同时还支持型,文心一言,腾讯混元, 讯飞星火,通义千问,DeepSeeK,智普等等国内各种大模型,可以更好地适应不同的应用场景,支持站点无限多开, 可以说ChatGPT付费创作系统目前国内相对体验比较好的一款的ChatGPT及多接口软件系统。 新增接入DeepSeek-R1、DeepSeek-V3(Ollama自部署和第三方均支持)、高级通道增加DeepSeek、 支持AI接口输出的reasoning_content字段(新的推理输出格式)、更新模型库、修复导出Excel的bug等功能, 优化了云灵Midjourney接口,出图更快更稳定。小程序端变化不大该系统版本测试下来比较完美, 老版本升级时数据库结构同步下,同时把原来
内容概要:本文档详细介绍了一款基于Java技术的美食点餐管理平台的设计与实现。该平台旨在优化传统餐饮行业的服务流程,通过智能化的点餐系统、高效的订单处理、智能库存管理和数据分析等功能,为用户提供便捷高效的点餐体验,并提升餐厅管理效率和服务质量。系统涵盖了前端设计、后端开发、数据库设计等方面,采用了成熟的Java技术和现代Web开发框架,如Spring Boot、Vue.js或React,确保系统的高效性和稳定性。此外,文档还包括详细的用户界面设计、模块实现以及系统部署指南,帮助开发者理解和搭建该平台。 适合人群:具备一定的Java编程基础和技术经验的研发人员、IT从业者以及有意开发类似系统的企业和个人。 使用场景及目标:①为餐厅提供一个集点餐、订单处理、库存管理于一体的高效平台;②优化传统餐饮服务流程,提升客户服务体验;③利用大数据分析辅助决策,助力餐饮企业精细化运营;④通过集成多种支付方式和其他外部系统,满足多样化的商业需求。 其他说明:本项目不仅提供了完整的技术方案和支持文档,还针对实际应用场景提出了多个扩展方向和技术优化思路,旨在引导用户不断迭代和完善该平台的功能和性能。
相场模拟与激光制造技术:选择性激光烧结、激光融覆中的凝固与枝晶生长研究,相场模拟与激光制造技术:选择性激光烧结、激光融覆及凝固过程中的枝晶生长研究,相场模拟 选择性激光烧结 激光融覆 凝固 枝晶生长 ,相场模拟; 选择性激光烧结; 激光融覆; 凝固; 枝晶生长,相场模拟与激光工艺:枝晶生长的凝固过程研究
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
关于加强新能源汽车安全管理涉及的法规标准分析.pptx
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
UI+svg格式
关于乘用车燃料消耗量评价方法及指标强制性国家标准的分析.pptx
1、文件内容:openjpeg-1.5.1-18.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/openjpeg-1.5.1-18.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
FPGA Verilog实现BT656与1120视频协议组帧解帧代码详解:含文档介绍与仿真验证,FPGA Verilog实现BT656与1120视频协议组帧解帧代码详解:含文档介绍与仿真验证,fpga verilog实现视频协议bt656和1120组帧解帧代码 有文档介绍协议,有mod仿真,matlab代码仿真 ,FPGA; Verilog; BT656协议; 1120组帧解帧代码; 文档介绍; Mod仿真; Matlab代码仿真,FPGA Verilog:实现BT656与1120组帧解帧代码的仿真与文档化研究
基于 RAG 与大模型技术的医疗问答系统,利用 DiseaseKG 数据集与 Neo4j 构 建知识图谱,结合 BERT 的命名实体识别和 34b 大模型的意图识别,通过精确的知识检索和问答生成, 提升系统在医疗咨询中的性能,解决大模型在医疗领域应用的可靠性问题。.zip项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用
抖音视频带货:行业趋势与营销策略.pptx
西门子动态密码程序:学习随机码生成与指针存储数据,Smartline触摸屏操作指南及编程视频教程,西门子动态密码程序:学习随机码生成与存储数据的智能之旅(视频讲解),200smart动态密码程序,触摸屏是smartline,西门子动态密码程序,,随机码的产生,指针用法存储数据,非常适合学习,而且是自己程序,还专门录制了一段视频来讲解编程的思路和画面的操作步骤。 ,200smart动态密码程序; touchscreen: smartline; 西门子动态密码程序; 随机码生成; 指针用法存储数据; 自学编程; 程序录制视频讲解。,西门子动态密码程序:触摸屏Smartline随机码生成与指针存储技术解析
项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用