- 浏览: 300735 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (148)
- wicket (3)
- 算法,数据结构 (1)
- 其他 (1)
- jdbc (2)
- mysql (10)
- php (18)
- gwt中文文档 (0)
- jquery (2)
- smil教程 (2)
- 开源知识 (1)
- mms彩信 (2)
- java (12)
- centos (3)
- linux (2)
- php apc (1)
- java hibernate (4)
- xampp (1)
- tomcat (1)
- css调试 (3)
- jasperReport (3)
- js 效果 (3)
- apache (1)
- eclipse (6)
- ss7 (8)
- java log log4j (2)
- java jndi (1)
- ldap (2)
- activemq (3)
- spring security (4)
- java 注解 (0)
- thinking in java (3)
- hibernate (1)
- maven (1)
- wap push (2)
- memcached (7)
- java servlet (2)
- flash game (0)
- financial knowledge (6)
- protect eyes (1)
最新评论
-
u012359453:
我是Android开发的,最近需要做一个消息转发的后台,我写好 ...
使用Java Service Wrapper将java程序作为linux服务并且开机自动启动 -
zhcheng:
我就是按照你这个配置的,别的地方都没有问题,只有在使用标签的时 ...
spring security3.0的ACL使用例子 -
xjjaid13:
...
js实现图片左右滚动 -
bhdweb:
项目中的角色名是死的?直接用户注解写在方法上?
spring security3.0的ACL使用例子 -
hw1287789687:
根本原因:我实体类中的类型是raw,没法直接实例化的类型。pr ...
hibernate错误:Could not determine type for: java.util.Set
这个例子是参考www.family168.com中的例子来做的,不过使用的是spring security 3.0.4。spring security的acl的默认使用的是用jdbc来对数据做持久化,因此这个例子也是在这个基础上来用的,在这个例子中使用的数据库是mysql。
首先是定义spring security的acl的四个基本表的sql定义:
CREATE TABLE `acl_sid` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `principal` tinyint(1) NOT NULL, `sid` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_uk_1` (`sid`,`principal`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; CREATE TABLE `acl_class` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `class` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_uk_2` (`class`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; CREATE TABLE `acl_object_identity` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `object_id_class` bigint(20) NOT NULL, `object_id_identity` bigint(20) NOT NULL, `parent_object` bigint(20) DEFAULT NULL, `owner_sid` bigint(20) NOT NULL, `entries_inheriting` tinyint(1) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_uk_3` (`object_id_class`,`object_id_identity`), KEY `foreign_fk_1` (`parent_object`), KEY `foreign_fk_3` (`owner_sid`), CONSTRAINT `acl_object_identity_ibfk_1` FOREIGN KEY (`parent_object`) REFERENCES `acl_object_identity` (`id`), CONSTRAINT `acl_object_identity_ibfk_2` FOREIGN KEY (`object_id_class`) REFERENCES `acl_class` (`id`), CONSTRAINT `acl_object_identity_ibfk_3` FOREIGN KEY (`owner_sid`) REFERENCES `acl_sid` (`id`) CREATE TABLE `acl_entry` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `acl_object_identity` bigint(20) NOT NULL, `ace_order` int(11) NOT NULL, `sid` bigint(20) NOT NULL, `mask` int(11) NOT NULL, `granting` tinyint(1) NOT NULL, `audit_success` tinyint(1) NOT NULL, `audit_failure` tinyint(1) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `unique_uk_4` (`acl_object_identity`,`ace_order`), KEY `foreign_fk_5` (`sid`), CONSTRAINT `acl_entry_ibfk_1` FOREIGN KEY (`acl_object_identity`) REFERENCES `acl_object_identity` (`id`), CONSTRAINT `acl_entry_ibfk_2` FOREIGN KEY (`sid`) REFERENCES `acl_sid` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
这四个表的说明如下:
1、ACL_SID让我们定义系统中唯一主体或授权(“SID”意思是“安全标识”——Spring Security Identity),是ACL认证对象。 它包含的列有ID,一个文本类型的SID,以及principal。
其中,SID是Security ID的简称,表示一个被认证对象。记录一个用户名(USERBASE.NAME)或角色名(ROLES.NAME) 。如果按角色认证,SID就是对应的角色,如果按用户名认证,SID就是对应的用户名。用来表示是否使用文本显示引用的主体名或一个GrantedAuthority。
而principal是认证规则。1 SID为用户名,0 SID为角色名。因此,对每个唯一的主体或GrantedAuthority都有单独一行。 在使用获得授权的环境下,一个SID通常叫做"recipient"授予者。
2、ACL_CLASS 让我们在系统中确定唯一的领域对象类。包含的列有ID和java类名。 因此,对每个我们希望保存ACL权限的类都有单独一行。其中,class是所要操作的域对象类型,它是域对象类型的全限定名。只有在此表中的CLASS,才被准许进行ACL授权及验证。
3、ACL_OBJECT_IDENTITY 为系统中每个唯一的领域对象实例保存信息。 列包括ID,指向ACL_CLASS的外键,唯一标识,所以我们知道为哪个ACL_CLASS实例提供信息,parent,一个外键指向ACL_SID 表,展示领域对象实例的拥有者,我们是否允许ACL条目从任何父亲ACL继承。 我们对每个领域对象实例有一个单独的行,来保存ACL权限。
4、ACL_ENTRY保存分配给每个授予者单独的权限,表示ACL授予者权限。
其中,acl_object_identity表示ACL_OBJECT_IDENTITY的外键。ace_order表示用于ACE集合排序 。sid表示recipient(比如一个ACL_SID外键),操作主体。mask表示一个整数位掩码,表示操作权限的掩码。 granting表示真实的权限被授权或被拒绝,1表示权限按MASK,0表示权限无效。 audit_success表示审计预留字段。 ,audit_failure表示审计预留字段。我们对于每个授予者都有单独一行,与领域对象工作获得一个权限。
二、配置aclService以及使用aclService
(1)首先是applicationContext-security.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.4.xsd "> <http auto-config='true'> <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" /> <intercept-url pattern="/**" access="ROLE_USER" /> </http> <sec:authentication-manager> <sec:authentication-provider> <user-service> <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" /> <user name="user" password="user" authorities="ROLE_USER" /> </user-service> </sec:authentication-provider> </sec:authentication-manager> <global-method-security secured-annotations="enabled" access-decision-manager-ref="aclAccessDecisionManager" /> </beans:beans>
(2)然后我们需要配置aclService,它负责与数据库进行交互:
a、我们要为acl配置cache,默认使用ehcache,spring security提供了一些默认的实现类。
<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache"> <constructor-arg ref="aclEhCache"/> </bean> <bean id="aclEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager" ref="cacheManager"/> <property name="cacheName" value="aclCache"/> </bean>
b、定义ehance.xml文件,在其中配置对应的aclCache缓存策略:
<ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> <cache name="aclCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="3600" overflowToDisk="true" /> </ehcache>
c、配置lookupStrategy。
简单来说,lookupStrategy的作用就是从数据库中读取信息,把这些信息提供给aclService使用,所以我们要为它配置一个dataSource,配置中还可以看到一个aclCache,这就是上面我们配置的缓存,它会把资源最大限度的利用起来。
<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy"> <constructor-arg ref="dataSource"/> <constructor-arg ref="aclCache"/> <constructor-arg> <bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl"> <constructor-arg> <list> <ref local="adminRole"/> <ref local="adminRole"/> <ref local="adminRole"/> </list> </constructor-arg> </bean> </constructor-arg> <constructor-arg> <bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/> </constructor-arg> </bean> <bean id="adminRole" class="org.springframework.security.core.authority.GrantedAuthorityImpl"> <constructor-arg value="ROLE_ADMIN"/> </bean>
中间一部分可能会让人感到困惑,为何一次定义了三个adminRole呢?这是因为一旦acl信息被保存到数据库中,无论是修改它的从属者,还是变 更授权,抑或是修改其他的ace信息,都需要控制操作者的权限,这里配置的三个权限将对应于上述的三种修改操作,我们把它配置成只有ROLE_ADMIN 才能执行这三种修改操作。
d、配置aclService
当我们已经拥有了dataSource, lookupStrategy和aclCache的时候,就可以用它们来组装aclService了,之后所有的acl操作都是基于aclService展开的:
<bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService"> <constructor-arg ref="dataSource"/> <constructor-arg ref="lookupStrategy"/> <constructor-arg ref="aclCache"/> <property name="classIdentityQuery" value="SELECT @@IDENTITY"/> <property name="sidIdentityQuery" value="SELECT @@IDENTITY"/> </bean>
这里要注意,如果上面的xml定义中没有:
<property name="classIdentityQuery" value="SELECT @@IDENTITY"/> <property name="sidIdentityQuery" value="SELECT @@IDENTITY"/>
这一部分的话,运行程序之后就会报以下的错误:
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: PROCEDURE xxxDB.identity does not exist
这主要是因为数据有区别导致的。在org.springframework.security.acls.jdbc.JdbcMutableAclService这个类中,classIdentityQuery 和sidIdentityQuery 的默认值都是“call identity() ”。如果在使用mysql时不给这两个属性赋值的话,就会报错。
(3)使用aclService管理acl信息
当我们添加了一条信息,要在acl中记录这条信息的ID,所有者,以及对应的授权信息。下列代码在添加信息后执行,用于添加对应的acl信息:
ObjectIdentity oid = new ObjectIdentityImpl(Message.class, message.getId()); MutableAcl acl = mutableAclService.createAcl(oid); acl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(owner), true); acl.insertAce(1, BasePermission.DELETE, new GrantedAuthoritySid("ROLE_ADMIN"), true); acl.insertAce(2, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER"), true); mutableAclService.updateAcl(acl);
第一步,根据class和id生成object的唯一标示。
第二步,根据object的唯一标示,创建一个acl。
第三步,为acl增加ace,这里我们让对象的所有者拥有对这个对象的“管理”权限,让“ROLE_ADMIN”拥有对这个对象的“删除”权限,让“ROLE_USER”拥有对这个对象的“读取”权限。
最后,更新acl信息。
当我们删除对象时,也要删除对应的acl信息。下列代码在删除信息后执行,用于删除对应的acl信息。
ObjectIdentity oid = new ObjectIdentityImpl(Message.class, id); mutableAclService.deleteAcl(oid, false);
使用class和id可以唯一标示一个对象,然后使用deleteAcl()方法将对象对应的acl信息删除。
(4)使用acl控制delete操作
上述代码中,除了对象的拥有者之外,我们还允许“ROLE_ADMIN”也可以删除对象,但是我们不会允许除此之外的其他用户拥有删除对象的权限,为了限制对象的删除操作,我们需要修改Spring Security的默认配置。
首先要增加一个对delete操作起作用的表决器:
<bean id="aclMessageDeleteVoter" class="org.springframework.security.acls.AclEntryVoter"> <constructor-arg ref="aclService"/> <constructor-arg value="ACL_MESSAGE_DELETE"/> <constructor-arg> <list> <util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/> <util:constant static-field="org.springframework.security.acls.domain.BasePermission.DELETE"/> </list> </constructor-arg> <property name="processDomainObjectClass" value="net.kentop.acl.object.Message"></property> </bean>
它只对Message这个类起作用,而且可以限制只有管理和删除权限的用户可以执行删除操作。
然后要将这个表决器添加到AccessDecisionManager中:
<bean id="aclAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> <property name="decisionVoters"> <list> <bean class="org.springframework.security.access.vote.RoleVoter"/> <ref local="aclMessageDeleteVoter"/> </list> </property> </bean>
现在AccessDecisionManager中有两个表决器了,除了默认的RoleVoter之外,又多了一个我们刚刚添加的aclMessageDeleteVoter。
现在可以把新的AccessDecisionManager赋予全局方法权限管理器了。
<global-method-security secured-annotations="enabled" access-decision-manager-ref="aclAccessDecisionManager" />
然后我们就可以在MessageService.java中使用Secured注解,控制删除操作了。
@Transactional @Secured("ACL_MESSAGE_DELETE") public void remove(Message message) { list.remove(message); ObjectIdentity oid = new ObjectIdentityImpl(Message.class, message.getId()); mutableAclService.deleteAcl(oid, false); }
实际上,我们最好不要让没有权限的操作者看到remove这个链接,可以使用taglib隐藏当前用户无权看到的信息。
<sec:accesscontrollist domainObject="${item}" hasPermission="8,16"> | <a href="message.do?action=remove&id=${item.id}" mce_href="message.do? action=remove&id=${item.id}">Remove</a> </sec:accesscontrollist>
8, 16是acl默认使用的掩码,8表示DELETE,16表示ADMINISTRATOR,当用户不具有这些权限的时候,他在页面上就看不到remove链接,也就无法执行操作了。
这比让用户可以执行remove操作,然后跑出异常,警告访问被拒绝要友好得多。
上面第二部分的xml定义全文如下,applicationContext-security-acl.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.4.xsd"> <bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache"> <constructor-arg ref="aclEhCache"/> </bean> <bean id="aclEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager" ref="cacheManager"/> <property name="cacheName" value="aclCache"/> </bean> <bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy"> <constructor-arg ref="dataSource"/> <constructor-arg ref="aclCache"/> <constructor-arg> <bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl"> <constructor-arg> <list> <ref local="adminRole"/> <ref local="adminRole"/> <ref local="adminRole"/> </list> </constructor-arg> </bean> </constructor-arg> <constructor-arg> <bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/> </constructor-arg> </bean> <bean id="adminRole" class="org.springframework.security.core.authority.GrantedAuthorityImpl"> <constructor-arg value="ROLE_ADMIN"/> </bean> <bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService"> <constructor-arg ref="dataSource"/> <constructor-arg ref="lookupStrategy"/> <constructor-arg ref="aclCache"/> <property name="classIdentityQuery" value="SELECT @@IDENTITY"/> <property name="sidIdentityQuery" value="SELECT @@IDENTITY"/> </bean> <bean id="aclMessageDeleteVoter" class="org.springframework.security.acls.AclEntryVoter"> <constructor-arg ref="aclService"/> <constructor-arg value="ACL_MESSAGE_DELETE"/> <constructor-arg> <list> <util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/> <util:constant static-field="org.springframework.security.acls.domain.BasePermission.DELETE"/> </list> </constructor-arg> <property name="processDomainObjectClass" value="net.kentop.acl.object.Message"></property> </bean> <bean id="aclAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased"> <property name="decisionVoters"> <list> <bean class="org.springframework.security.access.vote.RoleVoter"/> <ref local="aclMessageDeleteVoter"/> </list> </property> </bean> </beans>
三、该例子的项目文件:
(1)要操作的类:Message.java:
package net.kentop.acl.object; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.List; public class Message implements Serializable { private Long id; private String message; private String owner; private Date createDate; private Date updateDate; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public Date getUpdateDate() { return updateDate; } public void setUpdateDate(Date updateDate) { this.updateDate = updateDate; } }
MessageService.java
package net.kentop.acl.object; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.springframework.security.access.annotation.Secured; import org.springframework.security.acls.domain.BasePermission; import org.springframework.security.acls.domain.GrantedAuthoritySid; import org.springframework.security.acls.domain.ObjectIdentityImpl; import org.springframework.security.acls.domain.PrincipalSid; import org.springframework.security.acls.model.MutableAcl; import org.springframework.security.acls.model.MutableAclService; import org.springframework.security.acls.model.ObjectIdentity; import org.springframework.transaction.annotation.Transactional; public class MessageService { private List<Message> list = new ArrayList<Message>(); private MutableAclService mutableAclService; public void setMutableAclService(MutableAclService mutableAclService) { this.mutableAclService = mutableAclService; } @Secured({"ROLE_USER", "AFTER_ACL_READ"}) public Message get(Long id) { for (Message message : list) { if (message.getId().equals(id)) { return message; } } return null; } @Secured({"ROLE_USER", "AFTER_ACL_COLLECTION_READ"}) public List getAll() { return list; } @Transactional @Secured("ROLE_USER") public void save(String messageContent, String owner) { Message message = new Message(); message.setId(System.currentTimeMillis()); message.setMessage(messageContent); message.setOwner(owner); message.setCreateDate(new Date()); message.setUpdateDate(new Date()); list.add(message); ObjectIdentity oid = new ObjectIdentityImpl(Message.class, message.getId()); MutableAcl acl = mutableAclService.createAcl(oid); acl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(owner), true); acl.insertAce(1, BasePermission.DELETE, new GrantedAuthoritySid("ROLE_ADMIN"), true); acl.insertAce(2, BasePermission.READ, new GrantedAuthoritySid("ROLE_USER"), true); mutableAclService.updateAcl(acl); } public void update(Long id, String messageContent) { Message message = this.get(id); message.setMessage(messageContent); message.setUpdateDate(new Date()); } public void removeById(Long id) { Message message = this.get(id); this.remove(message); } @Transactional @Secured("ACL_MESSAGE_DELETE") public void remove(Message message) { list.remove(message); ObjectIdentity oid = new ObjectIdentityImpl(Message.class, message.getId()); mutableAclService.deleteAcl(oid, false); } }
MessageServlet.java:
package net.kentop.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.kentop.acl.object.Message; import net.kentop.acl.object.MessageService; import org.springframework.context.ApplicationContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.context.support.WebApplicationContextUtils; public class MessageServlet extends HttpServlet { private MessageService messageService; private MessageService getMessageService() { if (messageService == null) { ApplicationContext ctx = WebApplicationContextUtils .getWebApplicationContext(this.getServletContext()); messageService = (MessageService) ctx.getBean("messageService"); } return messageService; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { try { process(request, response); } catch (Exception ex) { throw new ServletException(ex); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { try { process(request, response); } catch (Exception ex) { throw new ServletException(ex); } } public void process(HttpServletRequest request, HttpServletResponse response) throws Exception { String action = request.getParameter("action"); if ("view".equals(action)) { this.view(request, response); } else if ("list".equals(action)) { this.list(request, response); } else if ("save".equals(action)) { this.save(request, response); } else if ("update".equals(action)) { this.update(request, response); } else if ("remove".equals(action)) { this.remove(request, response); } else if ("create".equals(action)) { this.create(request, response); } else if ("edit".equals(action)) { this.edit(request, response); } else { System.out.println("Unkown Action: " + action); } } public void view(HttpServletRequest request, HttpServletResponse response) throws Exception { Long id = Long.valueOf(request.getParameter("id")); Message message = getMessageService().get(id); request.setAttribute("message", message); request.getRequestDispatcher("/message-view.jsp") .forward(request, response); } public void list(HttpServletRequest request, HttpServletResponse response) throws Exception { List<Message> list = getMessageService().getAll(); request.setAttribute("list", list); request.getRequestDispatcher("/message-list.jsp") .forward(request, response); } public void save(HttpServletRequest request, HttpServletResponse response) throws Exception { String message = request.getParameter("message"); UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext() .getAuthentication() .getPrincipal(); String username = userDetails.getUsername(); getMessageService().save(message, username); response.sendRedirect("message.do?action=list"); } public void update(HttpServletRequest request, HttpServletResponse response) throws Exception { Long id = Long.valueOf(request.getParameter("id")); String message = request.getParameter("message"); getMessageService().update(id, message); response.sendRedirect("message.do?action=list"); } public void remove(HttpServletRequest request, HttpServletResponse response) throws Exception { Long id = Long.valueOf(request.getParameter("id")); getMessageService().removeById(id); response.sendRedirect("message.do?action=list"); } public void create(HttpServletRequest request, HttpServletResponse response) throws Exception { request.getRequestDispatcher("/message-edit.jsp") .forward(request, response); } public void edit(HttpServletRequest request, HttpServletResponse response) throws Exception { Long id = Long.valueOf(request.getParameter("id")); Message message = getMessageService().get(id); request.setAttribute("message", message); request.getRequestDispatcher("/message-edit.jsp") .forward(request, response); } }
(2)web.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!-- - Tutorial web application - --> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>acltest</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-*.xml</param-value> </context-param> <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>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>MessageServlet</servlet-name> <servlet-class>net.kentop.servlet.MessageServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MessageServlet</servlet-name> <url-pattern>/message.do</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
(3)jsp文件:
message_list.jsp:
<%@page contentType="text/html;charset=UTF-8"%> <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <c:set var="ctx" value="${pageContext.request.contextPath}" /> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>list</title> </head> <body> <table width="100%"> <tr> <td><a href="message.do?action=create" mce_href="message.do?action=create">Create Message</a></td> <td align="right">username: <sec:authentication property="name" /> | <a href="j_spring_security_logout" mce_href="j_spring_security_logout">logout</a></td> </tr> </table> <hr> <table border="1" width="100%"> <tr> <th>ID</th> <th>Message</th> <th>Owner</th> <th>Create Date</th> <th>Update Date</th> <th>Operation</th> </tr> <c:forEach var="item" items="${list}"> <tr> <td>${item.id} </td> <td>${item.message} </td> <td>${item.owner} </td> <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${item.createDate}" /> </td> <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${item.updateDate}" /> </td> <td><a href="message.do?action=view&id=${item.id}" mce_href="message.do?action=view&id=${item.id}">View</a> | <a href="message.do?action=edit&id=${item.id}">Update</a> <sec:accesscontrollist domainObject="${item}" hasPermission="8,16"> | <a href="message.do?action=remove&id=${item.id}" mce_href="message.do?action=remove&id=${item.id}">Remove</a> </sec:accesscontrollist></td> </tr> </c:forEach> </table> </body> </html>
message_edit.jsp:
<%@page contentType="text/html;charset=UTF-8"%> <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <c:set var="ctx" value="${pageContext.request.contextPath}"/> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <title>edit</title> </head> <body> <table width="100%"> <tr> <td><a href="message.do?action=list" mce_href="message.do?action=list">Back</a></td> <td align="right"> username: <sec:authentication property="name"/> | <a href="j_spring_security_logout" mce_href="j_spring_security_logout">logout</a> </td> </tr> </table> <hr> <fieldset> <legend>Message Info</legend> <form method="post" action="message.do?action=${param.action == 'create' ? 'save' : 'update'}"> <input type="hidden" name="id" value="${message.id}"> <table> <tr> <td>Message:</td> <td><input type="text" name="message" value="${message.message}"></td> </tr> <tr> <td colspan="2"> <input type="submit"> <input type="reset"> </td> </tr> </table> </form> </fieldset> </body> </html>
message_view.jsp:
<%@page contentType="text/html;charset=UTF-8"%> <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <c:set var="ctx" value="${pageContext.request.contextPath}"/> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <title>view</title> </head> <body> <table width="100%"> <tr> <td><a href="message.do?action=list" mce_href="message.do?action=list">Back</a></td> <td align="right"> username: <sec:authentication property="name"/> | <a href="j_spring_security_logout" mce_href="j_spring_security_logout">logout</a> </td> </tr> </table> <hr> <fieldset> <legend>Message Info</legend> <table> <tr> <td>ID:</td> <td>${message.id}</td> </tr> <tr> <td>Message:</td> <td>${message.message}</td> </tr> <tr> <td>Owner:</td> <td>${message.owner}</td> </tr> <tr> <td>Create Date:</td> <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${message.createDate}"/></td> </tr> <tr> <td>Update Date:</td> <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${message.updateDate}"/></td> </tr> </table> </fieldset> </body> </html>
四、整个项目的下载地址如下:
http://download.csdn.net/source/2851702
评论
java.lang.NullPointerException
org.springframework.security.taglibs.authz.AccessControlListTag.doStartTag(AccessControlListTag.java:92)
<sec:accesscontrollist domainObject="${item }" hasPermission="8">
版本是3.1.3
这是怎么个情况啊。
select * from acl_sid
drop table acl_sid
CREATE TABLE acl_sid (
id bigint(20) NOT NULL AUTO_INCREMENT,
principal tinyint(1) NOT NULL,
sid varchar(100) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY unique_uk_1 (sid,principal)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
select * from acl_class
drop table acl_class
CREATE TABLE acl_class (
id bigint(20) NOT NULL AUTO_INCREMENT,
class varchar(100) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY unique_uk_2 (class)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
select * from acl_object_identity
drop table acl_object_identity
CREATE TABLE acl_object_identity (
id bigint(20) NOT NULL AUTO_INCREMENT,
object_id_class bigint(20) NOT NULL,
object_id_identity bigint(20) NOT NULL,
parent_object bigint(20) DEFAULT NULL,
owner_sid bigint(20) NOT NULL,
entries_inheriting tinyint(1) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY unique_uk_3 (object_id_class,object_id_identity),
KEY foreign_fk_1 (parent_object),
KEY foreign_fk_3 (owner_sid),
CONSTRAINT acl_object_identity_ibfk_1 FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id),
CONSTRAINT acl_object_identity_ibfk_2 FOREIGN KEY (object_id_class) REFERENCES acl_class (id),
CONSTRAINT acl_object_identity_ibfk_3 FOREIGN KEY (owner_sid) REFERENCES acl_sid (id)
)
CREATE TABLE acl_entry (
id bigint(20) NOT NULL AUTO_INCREMENT,
acl_object_identity bigint(20) NOT NULL,
ace_order int(11) NOT NULL,
sid bigint(20) NOT NULL,
mask int(11) NOT NULL,
granting tinyint(1) NOT NULL,
audit_success tinyint(1) NOT NULL,
audit_failure tinyint(1) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY unique_uk_4 (acl_object_identity,ace_order),
KEY foreign_fk_5 (sid),
CONSTRAINT acl_entry_ibfk_1 FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity (id),
CONSTRAINT acl_entry_ibfk_2 FOREIGN KEY (sid) REFERENCES acl_sid (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aclCache' defined in file [G:\apache-tomcat-6.0.18\webapps\acltest\WEB-INF\classes\applicationContext-security-acl.xml]: Cannot resolve reference to bean 'aclEhCache' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aclEhCache' defined in file [G:\apache-tomcat-6.0.18\webapps\acltest\WEB-INF\classes\applicationContext-security-acl.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: net/sf/ehcache/Ehcache
相关推荐
早一段时间学习了springsecurity3.0 框架,在开始阶段不知道导入那些必需jar包,经过摸索,总结出来最精简的jar包
spring security3.0权限控制方面的文档
教你使用 SpringSecurity 3.0 一步一步教你使用SpringSecurity,从保护web应用到保护业务方法调用
spring-security-web-3.0 spring-security-taglibs-3.0 spring-security-openid-3.0 spring-security-core-3.0 spring-security-config-3.0 spring-security-aspects-3.0 spring-security-acl-3.0
SpringSecurity3.0相对比较稳定。本实例包含SpringSecurity3.0的基本配置,包含所需的Jar包和mysql数据库文件,直接导入myeclipes中并导入数据库即可运行,配置文件简单易懂,适合SpringSecurity初学者配置入门。...
SpringSecurity3.0 教程 价值不错哦!
简单springsecurity3.0的例子 做了详细注释,另外集成了tiles 和conversion插件,希望对你有帮助,里面有不对的地方请给我留言,我加你QQ一起讨论..注:我是通过maven管理的,如果你不是的话可能无法运行起来,只能看代码
SpringSecurity3.0实现
英文版本,主要对spring security 3.0.x 进行了介绍, 以及如何使用spring 的 安全架构来进行 web 开发.
Spring Security 3.0 权限管理精通,该系统是spring提供的企业级权限系统解决方案,因其优越的特性被广泛应用
spring security3.0.4 的acl使用例子,相关的说明在 http://blog.csdn.net/lhx1026/archive/2010/11/22/6027125.aspx
SpringSecurity3.0.x官方参考文档(英文+中文双解版)
超级详细的spring security3.0教程,包含spring security安全框架的历史和来源,一步一步的教你如何实现项目的安全实现
spring security acl 代码实例 spring security acl 代码实例spring security acl 代码实例spring security acl 代码实例spring security acl 代码实例spring security acl 代码实例
spring security3.0所有最新开发包及源码及文档 欢迎大家下载,祝大家学习愉快!。
Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架。
Spring-Security3.0自定义表结构
Spring Security 3.0 安全权限管理手册(最新),可以作为公司权限管理资料用,权限管理将是系统中的非常重要的一个模块,权限的设计也是参考相关资料进行整理和补充。系统将通过数据库进行管理用户权限
一步一步教你使用spring Security3
介绍一个基于Spring Boot 3.0、Spring Cloud 2022 & Alibaba的微服务RBAC权限管理系统。该系统可以实现微服务RBAC权限管理,通过RBAC权限管理机制对用户访问系统的权限进行限制,从而提高系统的安全性和可用性。同时...