关于web中的权限管理,一直是很麻烦的事,有人说struts2提供的拦截器的功能可以轻松实现权限的控制,我这边实现了一下,发现不是很完美,例如,页面的访问就控制不了,但是网上也提供了解决的方案,可以用过虑器来控制页面,也就是struts2的拦截器控制action的权限,过虑器来控制页面访问权限,貌似不错,但是代价太高了,另一种方案是采用spring security,反正是SSH的项目,spring security的应用还是相对成熟一些,做了一个实现,发现不少问题,记录下来。
表结构:
采用传统的 用户,角色,权限(资源),角色权限,用户角色 的模式,本来都是多对多的,为了简便都改成一对多和多对一了。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.coc.model.User" table="user">
<meta attribute="implement-equals">true</meta>
<cache usage="read-write"/>
<id name="id" type="java.lang.Integer">
<column name="userid" />
<generator class="assigned" />
</id>
<property name="username" type="java.lang.String">
<column name="username" length="40" not-null="true" />
</property>
<property name="nickname" type="java.lang.String">
<column name="nickname" length="40" not-null="true" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="40" not-null="true" />
</property>
<property name="email" type="java.lang.String">
<column name="email" length="100" not-null="true" />
</property>
<!-- <property name="deptid" type="java.lang.Integer">
<column name="deptid" not-null="true" />
</property>
-->
<property name="mobilepin" type="java.lang.String">
<column name="mobilepin" length="50" not-null="true" />
</property>
<property name="islockout" type="java.lang.Integer">
<column name="islockout" not-null="true" />
</property>
<property name="dtcreate" type="java.util.Date">
<column name="dtcreate" length="19" not-null="true" />
</property>
<property name="failtry" type="java.lang.Integer">
<column name="failtry" not-null="true" />
</property>
<property name="picurl" type="java.lang.String">
<column name="picurl" not-null="true" />
</property>
<property name="sex" type="java.lang.Integer">
<column name="sex" not-null="true" />
</property>
<property name="zip" type="java.lang.String">
<column name="zip" length="20" not-null="true" />
</property>
<property name="age" type="java.lang.Integer">
<column name="age" not-null="true" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" length="19" not-null="true" />
</property>
<property name="ismarry" type="java.lang.Integer">
<column name="ismarry" not-null="true" />
</property>
<property name="address" type="java.lang.String">
<column name="address" not-null="true" />
</property>
<property name="identity" type="java.lang.String">
<column name="identity" length="20" not-null="true" />
</property>
<property name="description" type="java.lang.String">
<column name="description" length="65535" not-null="true" />
</property>
<property name="issuper" type="java.lang.Integer">
<column name="issuper" not-null="true" />
</property>
<set name="useroles" cascade="all" inverse="true">
<key>
<column name="userid"/>
</key>
<one-to-many class="com.coc.model.Userole"/>
</set>
<many-to-one name="department" column="deptid" class="com.coc.model.Department"/>
</class>
</hibernate-mapping>
User Pojo:
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;
/**
* User entity.
*
* @author MyEclipse Persistence Tools
*/
public class User implements java.io.Serializable, UserDetails {
// Fields
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String username;
private String nickname;
private String password;
private String email;
private Integer deptid;
private String mobilepin;
private Integer islockout;
private Date dtcreate;
private Integer failtry;
private String picurl;
private Integer sex;
private String zip;
private Integer age;
private Date birthday;
private Integer ismarry;
private String address;
private String identity;
private String description;
private Integer issuper;
private Set <Userole> useroles =new HashSet<Userole>();
private Department department;
// Constructors
/** default constructor */
public User() {
}
// Property accessors
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getNickname() {
return this.nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getDeptid() {
return this.deptid;
}
public void setDeptid(Integer deptid) {
this.deptid = deptid;
}
public String getMobilepin() {
return this.mobilepin;
}
public void setMobilepin(String mobilepin) {
this.mobilepin = mobilepin;
}
public Integer getIslockout() {
return this.islockout;
}
public void setIslockout(Integer islockout) {
this.islockout = islockout;
}
public Date getDtcreate() {
return this.dtcreate;
}
public void setDtcreate(Date dtcreate) {
this.dtcreate = dtcreate;
}
public Integer getFailtry() {
return this.failtry;
}
public void setFailtry(Integer failtry) {
this.failtry = failtry;
}
public String getPicurl() {
return this.picurl;
}
public void setPicurl(String picurl) {
this.picurl = picurl;
}
public Integer getSex() {
return this.sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public String getZip() {
return this.zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return this.birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Integer getIsmarry() {
return this.ismarry;
}
public void setIsmarry(Integer ismarry) {
this.ismarry = ismarry;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getIdentity() {
return this.identity;
}
public void setIdentity(String identity) {
this.identity = identity;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getIssuper() {
return this.issuper;
}
public void setIssuper(Integer issuper) {
this.issuper = issuper;
}
public Set<Userole> getUseroles() {
return useroles;
}
public void setUseroles(Set<Userole> useroles) {
this.useroles = useroles;
}
public GrantedAuthority[] getAuthorities() {
List<GrantedAuthorityImpl> authoritis =new ArrayList<GrantedAuthorityImpl>();
Iterator<Userole> iter =useroles.iterator();
while(iter.hasNext())
{
Userole userole =(Userole)iter.next();
authoritis.add(new GrantedAuthorityImpl(userole.getRole().getRolename()));
}
return authoritis.toArray(new GrantedAuthorityImpl[authoritis.size()]);
}
public boolean isAccountNonExpired() {
return true;
}
public boolean isAccountNonLocked() {
return true;
}
public boolean isCredentialsNonExpired() {
return true;
}
public boolean isEnabled() {
return true;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
Userole表:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.coc.model.Userole" table="userole" >
<meta attribute="implement-equals">true</meta>
<cache usage="read-write"/>
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="assigned" />
</id>
<!--
<property name="userid" type="java.lang.Integer">
<column name="userid" not-null="true" />
</property>
<property name="roleid" type="java.lang.Integer">
<column name="roleid" not-null="true" />
</property>
-->
<many-to-one name="user" column="userid" class="com.coc.model.User" not-null="true"/>
<many-to-one name="role" column="roleid" class="com.coc.model.Role" not-null="true"/>
</class>
</hibernate-mapping>
Userole的pojo
public class Userole implements java.io.Serializable {
// Fields
private Integer id;
private Integer userid;
private Integer roleid;
private Role role;
private User user;
// Constructors
/** default constructor */
public Userole() {
}
// Property accessors
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserid() {
return this.userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public Integer getRoleid() {
return this.roleid;
}
public void setRoleid(Integer roleid) {
this.roleid = roleid;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Role 表的mapping&pojo
Role表的mapping
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.coc.model.Role" table="role">
<meta attribute="implement-equals">true</meta>
<cache usage="read-write"/>
<id name="roleid" type="java.lang.Integer">
<column name="roleid" />
<generator class="assigned" />
</id>
<property name="rolename" type="java.lang.String">
<column name="rolename" length="50" not-null="true" />
</property>
<property name="issysrole" type="java.lang.Integer">
<column name="issysrole" not-null="true" />
</property>
<property name="islockout" type="java.lang.Integer">
<column name="islockout" not-null="true" />
</property>
<property name="description" type="java.lang.String">
<column name="description" not-null="true" />
</property>
<set name="useroles" cascade="all" inverse="true">
<key>
<column name="roleid"/>
</key>
<one-to-many class="com.coc.model.Userole"/>
</set>
<set name="rolePermissions" cascade="all" inverse="true">
<key>
<column name="roleid"/>
</key>
<one-to-many class="com.coc.model.Rolepermission"/>
</set>
</class>
</hibernate-mapping>
Role表的pojo
public class Role implements java.io.Serializable {
// Fields
private Integer roleid;
private String rolename;
private Integer issysrole;
private Integer islockout;
private String description;
private Set<Userole> useroles =new HashSet<Userole>();
private Set<Rolepermission> rolePermissions =new HashSet<Rolepermission>();
// Constructors
/** default constructor */
public Role() {
}
// Property accessors
public Integer getRoleid() {
return this.roleid;
}
public void setRoleid(Integer roleid) {
this.roleid = roleid;
}
public String getRolename() {
return this.rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public Integer getIssysrole() {
return this.issysrole;
}
public void setIssysrole(Integer issysrole) {
this.issysrole = issysrole;
}
public Integer getIslockout() {
return this.islockout;
}
public void setIslockout(Integer islockout) {
this.islockout = islockout;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public void setUseroles(HashSet<Userole> useroles) {
this.useroles = useroles;
}
public void setRolePermissions(HashSet<Rolepermission> rolePermissions) {
this.rolePermissions = rolePermissions;
}
public Set<Userole> getUseroles() {
return useroles;
}
public void setUseroles(Set<Userole> useroles) {
this.useroles = useroles;
}
public Set<Rolepermission> getRolePermissions() {
return rolePermissions;
}
public void setRolePermissions(Set<Rolepermission> rolePermissions) {
this.rolePermissions = rolePermissions;
}
}
Permission表的mapping及pojo
Permission 表的mapping
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.coc.model.Permission" table="permission">
<meta attribute="implement-equals">true</meta>
<cache usage="read-write"/>
<id name="permitid" type="java.lang.Integer">
<column name="permitid" />
<generator class="assigned" />
</id>
<property name="permitname" type="java.lang.String">
<column name="permitname" length="50" not-null="true" />
</property>
<property name="module" type="java.lang.String">
<column name="module" length="100" not-null="true" />
</property>
<property name="action" type="java.lang.String">
<column name="action" length="100" not-null="true" />
</property>
<property name="permitvalue" type="java.lang.String">
<column name="permitvalue" not-null="true" />
</property>
<property name="parentid" type="java.lang.Integer">
<column name="parentid" not-null="true" />
</property>
<property name="type" type="java.lang.Integer">
<column name="type" not-null="true" />
</property>
<property name="description" type="java.lang.String">
<column name="description" not-null="true" />
</property>
<set name="rolePermissions" cascade="all" inverse="true">
<key>
<column name="permitid"/>
</key>
<one-to-many class="com.coc.model.Rolepermission"/>
</set>
</class>
</hibernate-mapping>
Permission 表的pojo
public class Permission implements java.io.Serializable {
// Fields
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer permitid;
private String permitname;
private String module;
private String action;
private String permitvalue;
private Integer parentid;
private Integer type;
private String description;
private Set<Rolepermission> rolePermissions =new HashSet<Rolepermission>();
// Constructors
/** default constructor */
public Permission() {
}
// Property accessors
public Integer getPermitid() {
return this.permitid;
}
public void setPermitid(Integer permitid) {
this.permitid = permitid;
}
public String getPermitname() {
return this.permitname;
}
public void setPermitname(String permitname) {
this.permitname = permitname;
}
public String getModule() {
return this.module;
}
public void setModule(String module) {
this.module = module;
}
public String getAction() {
return this.action;
}
public void setAction(String action) {
this.action = action;
}
public String getPermitvalue() {
return this.permitvalue;
}
public void setPermitvalue(String permitvalue) {
this.permitvalue = permitvalue;
}
public Integer getParentid() {
return this.parentid;
}
public void setParentid(Integer parentid) {
this.parentid = parentid;
}
public Integer getType() {
return this.type;
}
public void setType(Integer type) {
this.type = type;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Rolepermission> getRolePermissions() {
return rolePermissions;
}
public void setRolePermissions(Set<Rolepermission> rolePermissions) {
this.rolePermissions = rolePermissions;
}
}
最后是RolePermission的
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.coc.model.Rolepermission" table="rolepermission">
<meta attribute="implement-equals">true</meta>
<cache usage="read-write"/>
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="assigned" />
</id>
<!--
<property name="roleid" type="java.lang.Integer">
<column name="roleid" not-null="true" />
</property>
<property name="permitid" type="java.lang.Integer">
<column name="permitid" not-null="true" />
</property>
-->
<many-to-one name="role" column="roleid" class="com.coc.model.Role" not-null="true" />
<many-to-one name="permission" column="permitid" class="com.coc.model.Permission" not-null="true"/>
</class>
</hibernate-mapping>
public class Rolepermission implements java.io.Serializable {
// Fields
private Integer id;
private Integer roleid;
private Integer permitid;
private Role role;
private Permission permission;
// Constructors
/** default constructor */
public Rolepermission() {
}
// Property accessors
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getRoleid() {
return this.roleid;
}
public void setRoleid(Integer roleid) {
this.roleid = roleid;
}
public Integer getPermitid() {
return this.permitid;
}
public void setPermitid(Integer permitid) {
this.permitid = permitid;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public Permission getPermission() {
return permission;
}
public void setPermission(Permission permission) {
this.permission = permission;
}
}
以上代码没得什么特别的,除了User实现了UserDetails的接口外,没有什么,可以看到这个接口是spring security提供的,其实现的具体方法是getAuthorities()通俗地说也就是把这个user所有角色的角色名提取出来.
另外在User的service的实现层也实现了spring security的一个接口,代码如下.
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import com.coc.hibernate.dao.UserDao;
import com.coc.model.User;
import com.coc.service.UserManager;
public class UserManagerImpl implements UserManager,UserDetailsService {
private UserDao userDao;
public User getUserByName(String userName) {
return userDao.findUserByName(userName);
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public UserDetails loadUserByUsername(String userName)
throws UsernameNotFoundException, DataAccessException {
User user = this.getUserByName(userName);
if(user==null)
{
throw new UsernameNotFoundException("User not found!");
}
return user;
}
public List<User> findAllUser(int start, int limit, String sortName,String order) {
return userDao.findAllUser(start, limit,sortName,order);
}
public Object getPageCount() {
return userDao.getPageCount();
}
public User loadUserById(Integer userId) {
return userDao.loadUserById(userId);
}
public void updateUser(User user)
{
userDao.saveorupdate(user);
}
}
到此为止,可以看出spring security通过实现这两个接口,拥有了用户及其角色的信息。
接下来要实现一个interceptor,spring security通过这个interceptor来判断用户的各个角色是否拥有相应的权限,如果有则放行,如果没有就拦截了,具体代码如下.
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.ConfigAttributeEditor;
import org.springframework.security.intercept.web.FilterInvocation;
import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.security.util.AntUrlPathMatcher;
import org.springframework.security.util.RegexUrlPathMatcher;
import org.springframework.security.util.UrlMatcher;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.coc.model.Permission;
import com.coc.model.Rolepermission;
import com.coc.service.PermissionManager;
public class SecureResourceFilterInvocationDefinitionSource implements
FilterInvocationDefinitionSource, InitializingBean {
private UrlMatcher urlMatcher;
private boolean useAntPath = true;
private boolean lowercaseComparisons = true;
private PermissionManager permissionManager;
/**
* @param useAntPath
* the useAntPath to set
*/
public void setUseAntPath(boolean useAntPath) {
this.useAntPath = useAntPath;
}
/**
* @param lowercaseComparisons
*/
public void setLowercaseComparisons(boolean lowercaseComparisons) {
this.lowercaseComparisons = lowercaseComparisons;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
//System.out.println("=========afterPropertiesSet()==========");
// default url matcher will be RegexUrlPathMatcher
this.urlMatcher = new RegexUrlPathMatcher();
if (useAntPath) { // change the implementation if required
this.urlMatcher = new AntUrlPathMatcher();
}
// Only change from the defaults if the attribute has been set
if ("true".equals(lowercaseComparisons)) {
if (!this.useAntPath) {
((RegexUrlPathMatcher) this.urlMatcher)
.setRequiresLowerCaseUrl(true);
}
} else if ("false".equals(lowercaseComparisons)) {
if (this.useAntPath) {
((AntUrlPathMatcher) this.urlMatcher)
.setRequiresLowerCaseUrl(false);
}
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.security.intercept.ObjectDefinitionSource#getAttributes(java.lang.Object)
*/
public ConfigAttributeDefinition getAttributes(Object filter)
throws IllegalArgumentException {
//System.out.println("=========getAttributes==========");
FilterInvocation filterInvocation = (FilterInvocation) filter;
String requestURI = filterInvocation.getRequestUrl();
requestURI=StringUtils.removeStart(requestURI, "/");
Map<String, String> urlAuthorities = this
.getUrlAuthorities(filterInvocation);
String grantedAuthorities = null;
for (Iterator<Map.Entry<String, String>> iter = urlAuthorities
.entrySet().iterator(); iter.hasNext();) {
Map.Entry<String, String> entry = iter.next();
String url = entry.getKey();
//System.out.println("============url key is "+url+"=================\n");
//System.out.println("============requestURI is "+requestURI+"=================\n");
if (urlMatcher.pathMatchesUrl(url, requestURI)) {
grantedAuthorities = entry.getValue();
System.out.println("============\n match url is "+url+"\n requestURI is +"+requestURI+"\n=================grantedAuthorities is "+grantedAuthorities+"\n");
break;
}
}
if (grantedAuthorities != null) {
ConfigAttributeEditor configAttrEditor = new ConfigAttributeEditor();
configAttrEditor.setAsText(grantedAuthorities);
return (ConfigAttributeDefinition) configAttrEditor.getValue();
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.springframework.security.intercept.ObjectDefinitionSource#getConfigAttributeDefinitions()
*/
@SuppressWarnings("unchecked")
public Collection getConfigAttributeDefinitions() {
return null;
}
/*
* (non-Javadoc)
*
* @see org.springframework.security.intercept.ObjectDefinitionSource#supports(java.lang.Class)
*/
@SuppressWarnings("unchecked")
public boolean supports(Class clazz) {
return true;
}
/**
*
* @param filterInvocation
* @return
*/
@SuppressWarnings("unchecked")
private Map<String, String> getUrlAuthorities(
FilterInvocation filterInvocation) {
System.out.println("=========getUrlAuthorities==========");
ServletContext servletContext = filterInvocation.getHttpRequest()
.getSession().getServletContext();
permissionManager=(PermissionManager)WebApplicationContextUtils.getWebApplicationContext(servletContext).getBean("permissionManager");
List<Permission> permissionList=permissionManager.loadUrlAuthorities();
Map<String, String> urlAuthorities =new HashMap<String, String>();
for(int i=0;i<permissionList.size();i++)
{
Permission permission=(Permission)permissionList.get(i);
Set rolePermission =permission.getRolePermissions();
Iterator iter=rolePermission.iterator();
List roleName =new ArrayList();
while(iter.hasNext())
{
Rolepermission rp =(Rolepermission)iter.next();
roleName.add(rp.getRole().getRolename());
}
//System.out.println("url value "+permission.getPermitvalue()+"\nrolenames "+StringUtils.join(roleName,","));
urlAuthorities.put(permission.getPermitvalue(), StringUtils.join(roleName,","));
}
return urlAuthorities;
// return (Map<String, String>) servletContext
// .getAttribute("urlAuthorities");
}
public PermissionManager getPermissionManager() {
return permissionManager;
}
public void setPermissionManager(PermissionManager permissionManager) {
this.permissionManager = permissionManager;
}
}
这里再将这些代码在spring scurity的配置文件中声明一下,就可以用了.
<?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:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<beans:bean id="loggerListener"
class="org.springframework.security.event.authentication.LoggerListener" />
<http access-denied-page="/403.jsp">
<intercept-url pattern="/static/**" filters="none" />
<intercept-url pattern="/template/**" filters="none" />
<intercept-url pattern="/images/**" filters="none" />
<intercept-url pattern="/css/**" filters="none" />
<intercept-url pattern="/js/**" filters="none" />
<intercept-url pattern="/dwr/**" filters="none" />
<intercept-url pattern="/uploads/**" filters="none" />
<intercept-url pattern="/" filters="none" />
<intercept-url pattern="/login.jsp" filters="none" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.action" default-target-url="/login.action" />
<logout logout-success-url="/login.jsp"/>
<http-basic />
</http>
<authentication-manager alias="authenticationManager"/>
<authentication-provider user-service-ref="userManager">
<!-- <password-encoder hash="md5"/>-->
</authentication-provider>
<beans:bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
<beans:property name="allowIfAllAbstainDecisions" value="false"/>
<beans:property name="decisionVoters">
<beans:list>
<beans:bean class="org.springframework.security.vote.RoleVoter"/>
<beans:bean class="org.springframework.security.vote.AuthenticatedVoter"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="resourceSecurityInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager"/>
<beans:property name="objectDefinitionSource" ref="secureResourceFilterInvocationDefinitionSource" />
<beans:property name="observeOncePerRequest" value="false" />
<custom-filter after="LAST" />
</beans:bean>
<beans:bean id="secureResourceFilterInvocationDefinitionSource" class="com.coc.security.interceptor.SecureResourceFilterInvocationDefinitionSource" />
<!-- internationalization-->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:/messages"/>
</beans:bean>
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"/>
</beans:beans>
http的定义中定义了不需要过滤的一些资源,当用户无权访问时将转到403.jsp的页面,其中如果用户成功登陆,我这里将其转至一个login.action,做一些后续的处理,而没有直接转入一个成功页面,其中<authentication-provider user-service-ref="userManager"> 的userManager就是我们user的service层.因为实现了spring security的接口所以声明,另外还有SecureResourceFilterInvocationDefinitionSource的声明,这样,程序可以运行并做出权限的判断。
说明一下,数据库中没有指派给任何Role的资源视为是都可以访问的资源,一旦指明了Role,就要通过权限来访问了.
不知如何解决的问题:
1)登陆时用户名不能为中文,这个问题困扰了很久,没得解决,不知为什么!因为登陆交给了spring scurity,所以不知如何查,不知哪位高手解决过这个问题。
2)由于SecureResourceFilterInvocationDefinitionSource 这个interceptor要进行Role名与资源权限的判断以此来验证用户是否具有权限,有人提出在系统启动时将资源权限一次性load进来,但是如果有更新,不是要重启系统来重新载入!不知有没有更好的办法,我的里面是每次都取,这个显然的没有效率的.