Spring Security 3.0配置
本文说明和参考:http://panyongzheng.iteye.com/blog/1476079
应该注意的扫描顺序:http://panyongzheng.iteye.com/blog/1477691
几个有用的资料:
spring-security 帮助文档中整理出来的简单记录摘要:http://mislay.iteye.com/blog/411323
在spring security使用方法保护:http://marshal.easymorse.com/archives/1260
SpringSecurity笔记3-Securing Methods:http://springsfeng.iteye.com/blog/1295102
xml被扫描顺序参考: http://sence-qi.iteye.com/blog/1328902
由于服务器启动时的加载配置文件的顺序为web.xml---root-context.xml(Spring的配置文件)---servlet-context.xml(SpringMVC的配置文件),由于root-context.xml配置文件中Controller会先进行扫描装配,但是此时service还没有进行事务增强处理,得到的将是原样的Service(没有经过事务加强处理,故而没有事务处理能力)
先按照http://panyongzheng.iteye.com/blog/1475762这里配置完SpringMVC&Hibernate,在增加spring能力时,同时选择spring security jar,并实现全注解方式。注意:service.impl里面的类,如是要是先回滚,那应该throws RuntimeException。
认证管理的几种方式:
<!-- 权限管理操作 --> <authentication-manager> <authentication-provider> <!-- 密码加密方式. 常用的有md5 和 sha. salt-source:忘记了.. 手头api关了,网速卡就不上网查了. 类似在md5上又加了一层. 放置暴力破解. 追加安全性. <password-encoder hash="md5"> <salt-source user-property="username"/> </password-encoder> --> <!-- 注入dataSource验证数据库中的用户名.密码.账号状态.和权限相关; --> <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password,enabled from user where username = ? and enabled = 1" authorities-by-username-query="select u.username,r.name from user u join user_role ur on u.uid = ur.uid join role r on r.rid = ur.rid where u.username = ?" /> <!-- 使用固定的用户名和密码及权限来做验证. <user-service> <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" /> <user name="user" password="user" authorities="ROLE_USER" /> </user-service> --> </authentication-provider>
<global-method-security secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled"/>
@Override@Transactional(propagation=Propagation.REQUIRED,readOnly=true)@Secured("ROLE_USER")public List<Users> selectUsers() throws RuntimeException{// TODO Auto-generated method stubreturn usersDAO.selectUsers();}<beans ...... xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation=" ...... http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">............<security:global-method-security secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled"/>
@SuppressWarnings("unchecked")@RequestMapping(value="/saveAndSearch.do")@Secured("ROLE_USER")public ModelAndView search(){ ModelAndView view = new ModelAndView("list"); Users users = new Users(); users.setName("Pandy"); users.setPassword("password"); //helloService.insertUsers(users); List<Users> list = helloService.selectUsers(); System.out.println("list.size()="+list.size()); view.addObject("message","Search Successful! counter="+list.size()); return view; }DROP TABLE IF EXISTS `users`;CREATE TABLE `users` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `password` varchar(20) DEFAULT NULL, `email` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `roles`; CREATE TABLE `roles` ( `id` int(10) NOT NULL auto_increment, `name` varchar(20) default NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `authorities`;CREATE TABLE `authorities` ( `id` int(10) NOT NULL AUTO_INCREMENT, `description` varchar(100) DEFAULT NULL, `url` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `users_roles`; CREATE TABLE `users_roles` ( `user_id` int(10) NOT NULL, `role_id` int(10) NOT NULL, PRIMARY KEY (`user_id`,`role_id`), KEY `FK_R_2` (`role_id`), CONSTRAINT `FK_R_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), CONSTRAINT `FK_R_2` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`)
DROP TABLE IF EXISTS `roles_authorities`; CREATE TABLE `roles_authorities` ( `role_id` int(10) NOT NULL, `authority_id` int(10) NOT NULL, PRIMARY KEY (`role_id`,`authority_id`), KEY `FK_R_4` (`authority_id`), CONSTRAINT `FK_R_3` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`), CONSTRAINT `FK_R_4` FOREIGN KEY (`authority_id`) REFERENCES `authorities` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
<?xml version="1.0" encoding="UTF-8"?><web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name> <context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><servlet> <servlet-name>SpringMVCSecurityDemo</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SpringMVCSecurityDemo</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- SpringSecurity filter--> <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> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list></web-app>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"><!-- 这里启动Controller层方法保护 --> <security:global-method-security secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled"/> <mvc:annotation-driven /> <!-- 这里只扫描Controller --> <context:component-scan base-package="com" use-default-filters="false" > <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/> </context:component-scan> <bean value="/pages/"></property><property name="suffix" value=".jsp"></property></bean></beans>
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"default-autowire="byName" default-lazy-init="true"><!-- 这里只扫描Service --><context:component-scan base-package="com" > <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/> </context:component-scan> <bean id="dataSource" value="com.mysql.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/test"></property><property name="username" value="root"></property></bean><bean id="sessionFactory"/></property><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop></props></property></bean><bean id="transactionManager"/></property></bean><bean id="webApplicationUtils" lazy-init="false"/><tx:annotation-driven transaction-manager="transactionManager" /><import resource="applicationContext-security.xml"/></beans>
package com.common;import javax.servlet.ServletContext;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.web.context.ServletContextAware;/* * 当我们无法拿到bean的时候,可以通过这样的方式反注入得到WebApplicationContext,然后在getBean(); */public class WebApplicationUtils implements ApplicationContextAware,ServletContextAware{public static ApplicationContext applicationContext = null;public static ServletContext servletContext = null;private static SessionFactory factory;private static Session session;public static SessionFactory getFactory() {factory = (SessionFactory)WebApplicationUtils.getApplicationContext().getBean("sessionFactory");return factory;}public static Session getSession() {session = getFactory().getCurrentSession();return session;}public void setApplicationContext(ApplicationContext actx) throws BeansException {if(WebApplicationUtils.applicationContext==null){WebApplicationUtils.applicationContext = actx;}}public void setServletContext(ServletContext sctx) {if(WebApplicationUtils.servletContext==null){WebApplicationUtils.servletContext=sctx;}}public static ApplicationContext getApplicationContext() {return applicationContext;}public static ServletContext getServletContext() {return servletContext;}}package com.dao.impl;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 org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import org.springframework.security.access.ConfigAttribute;import org.springframework.security.access.SecurityConfig;import org.springframework.stereotype.Repository;import com.dao.IAuthoritiesDAO;import com.pojo.Authorities;import com.pojo.RolesAuthorities;@Repositorypublic class AuthoritiesDAO extends HibernateDaoSupport implements IAuthoritiesDAO {@Autowired public void setSessionFactoryOverride(SessionFactory sessionFactory) { super.setSessionFactory(sessionFactory); }@Overridepublic Map<String, Collection<ConfigAttribute>> getResourceMap() {Map<String, Collection<ConfigAttribute>> resourceMap = new HashMap<String, Collection<ConfigAttribute>>();/*Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();ConfigAttribute adminCA = new SecurityConfig("ROLE_ADMIN");atts.add(adminCA);ConfigAttribute userCA = new SecurityConfig("ROLE_USER");atts.add(userCA);resourceMap.put("/index.jsp", atts);*/List<Authorities> list = getAll();for(Authorities auth : list){Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();String url = auth.getUrl();System.out.println("URL="+url);if(auth.getRolesAuthoritieses()!=null){Iterator it = auth.getRolesAuthoritieses().iterator();while(it.hasNext()){RolesAuthorities ra = (RolesAuthorities)it.next();String rolesName = ra.getRoles().getName();ConfigAttribute ca = new SecurityConfig(rolesName);atts.add(ca);System.out.println("rolesName="+rolesName);}}resourceMap.put(url, atts);System.out.println("---------------------------------------");}return resourceMap;}public List<Authorities> getAll(){String hql="from com.pojo.Authorities";List<Authorities> list = getHibernateTemplate().find(hql);return list;}}package com.dao.impl;import java.util.List;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import org.springframework.stereotype.Repository;import com.dao.IRolesDAO;import com.pojo.Roles;@Repositorypublic class RolesDAO extends HibernateDaoSupport implements IRolesDAO {@Autowired public void setSessionFactoryOverride(SessionFactory sessionFactory) { super.setSessionFactory(sessionFactory); }@Overridepublic Roles getRolesById(Integer id) {// TODO Auto-generated method stubString hql="from com.pojo.Roles a where a.id=?";List<Roles> list = getHibernateTemplate().find(hql,new Integer[]{id});if(list!=null&&list.size()>0) return list.get(0);return null;}}package com.dao.impl;import java.util.List;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import org.springframework.stereotype.Repository;import com.dao.IUsersDAO;import com.pojo.Roles;import com.pojo.Users;@Repositorypublic class UsersDAO extends HibernateDaoSupport implements IUsersDAO {@Autowired public void setSessionFactoryOverride(SessionFactory sessionFactory) { super.setSessionFactory(sessionFactory); }@Overridepublic void insertUsers(Users users) {// TODO Auto-generated method stubgetHibernateTemplate().saveOrUpdate(users);}@Override@SuppressWarnings("unchecked")public List<Users> selectUsers() {// TODO Auto-generated method stubString sql = "From com.pojo.Users Order By id";List<Users> list = getHibernateTemplate().find(sql);return list;}@Overridepublic Users getUserByUserName(String username) {// TODO Auto-generated method stubSystem.out.println("@@@@@@@@@getUserByUserName");String sql = "From com.pojo.Users where name=? Order By id";List<Users> list = getHibernateTemplate().find(sql,new String[]{username});if(list!=null&&list.size()>0) return list.get(0);return null;}}package com.controller;import java.util.List;import javax.annotation.Resource;import javax.annotation.security.RolesAllowed;import org.springframework.security.access.annotation.Secured;import org.springframework.security.access.prepost.PreAuthorize;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import com.pojo.Users;import com.service.IHelloService;@Controllerpublic class HelloController {private String viewName;@Resource(name="helloService") private IHelloService helloService; public String getViewName() {return viewName;}public void setViewName(String viewName) {this.viewName = viewName;} @SuppressWarnings("unchecked")@RequestMapping(value="/saveAndSearch.do")public ModelAndView search(){ ModelAndView view = new ModelAndView("list"); Users users = new Users(); users.setName("Pandy"); users.setPassword("password"); //helloService.insertUsers(users); List<Users> list = helloService.selectUsers(); System.out.println("list.size()="+list.size()); view.addObject("message","Search Successful! counter="+list.size()); return view; }@SuppressWarnings("unchecked")@RequestMapping(value="/search1.do")@Secured("ROLE_USER")public ModelAndView search1(){ ModelAndView view = new ModelAndView("list"); List<Users> list = helloService.selectUsers(); view.addObject("message","Search Successful! counter="+list.size()); return view; }@SuppressWarnings("unchecked")@RequestMapping(value="/search2.do")@RolesAllowed("ROLE_ADMIN")public ModelAndView search2(){ ModelAndView view = new ModelAndView("list"); List<Users> list = helloService.selectUsers(); view.addObject("message","Search Successful! counter="+list.size()); return view; }@SuppressWarnings("unchecked")@RequestMapping(value="/search3.do")@PreAuthorize("hasRole('ROLE_ADMIN')")public ModelAndView search3(){ ModelAndView view = new ModelAndView("list"); List<Users> list = helloService.selectUsers(); view.addObject("message","Search Successful! counter="+list.size()); return view; }}package com.service.impl;import java.util.List;import javax.annotation.Resource;import javax.annotation.security.RolesAllowed;import org.springframework.security.access.annotation.Secured;import org.springframework.security.access.prepost.PreAuthorize;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.dao.IUsersDAO;import com.pojo.Users;import com.service.IHelloService;@Service@Transactionalpublic class HelloService implements IHelloService {@Resource(name="usersDAO")public IUsersDAO usersDAO;@Override@Transactional(propagation=Propagation.REQUIRED)public void insertUsers(Users users) throws RuntimeException{usersDAO.insertUsers(users);}@Override@Transactional(propagation=Propagation.REQUIRED,readOnly=true)public List<Users> selectUsers() throws RuntimeException{// TODO Auto-generated method stubreturn usersDAO.selectUsers();}@Override@Transactional(propagation=Propagation.REQUIRED,readOnly=true)@Secured("ROLE_USER")public List<Users> selectUsers1() throws RuntimeException{// TODO Auto-generated method stubreturn usersDAO.selectUsers();}@Override@Transactional(propagation=Propagation.REQUIRED,readOnly=true)@RolesAllowed("ROLE_ADMIN")public List<Users> selectUsers2() throws RuntimeException{// TODO Auto-generated method stubreturn usersDAO.selectUsers();}@Override@Transactional(propagation=Propagation.REQUIRED,readOnly=true)@PreAuthorize("hasRole('ROLE_ADMIN')")public List<Users> selectUsers3() throws RuntimeException{// TODO Auto-generated method stubreturn usersDAO.selectUsers();}}package com.service.impl;import java.util.Collection;import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.access.ConfigAttribute;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.dao.IAuthoritiesDAO;import com.service.IAuthoritiesService;@Service@Transactionalpublic class AuthoritiesService implements IAuthoritiesService {@Autowiredpublic IAuthoritiesDAO authoritiesDAO;@Overridepublic Map<String, Collection<ConfigAttribute>> getResourceMap() {// TODO Auto-generated method stubreturn authoritiesDAO.getResourceMap();}}package com.service.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.dao.IRolesDAO;import com.pojo.Roles;import com.service.IRolesService;@Service@Transactionalpublic class RolesService implements IRolesService {@Autowiredpublic IRolesDAO rolesDAO;@Override@Transactional(propagation=Propagation.REQUIRED,readOnly=true)public Roles getRolesById(Integer id) {// TODO Auto-generated method stubreturn rolesDAO.getRolesById(id);}}package com.service.impl;import org.hibernate.Hibernate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import com.dao.IUsersDAO;import com.pojo.Users;import com.service.IUsersService;@Service@Transactionalpublic class UsersService implements IUsersService {@Autowiredpublic IUsersDAO usersDAO;@Override@Transactional(propagation=Propagation.REQUIRED,readOnly=true)public Users getUserByUserName(String username) {Users user = usersDAO.getUserByUserName(username);Hibernate.initialize(user.getUsersRoleses());return user;}}package com.security;import java.util.Collection;import java.util.Iterator;import java.util.Map;import org.springframework.security.access.ConfigAttribute;import org.springframework.security.web.FilterInvocation;import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;import org.springframework.security.web.util.AntUrlPathMatcher;import org.springframework.security.web.util.UrlMatcher;import com.common.WebApplicationUtils;import com.service.IAuthoritiesService;/** * 此类在初始化时,应该取到所有资源及其对应角色的定义 */// <!-- 资源源数据定义,即定义某一资源可以被哪些角色访问 -->public class MyInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {private UrlMatcher urlMatcher = new AntUrlPathMatcher();;private static Map<String, Collection<ConfigAttribute>> resourceMap = null;public MyInvocationSecurityMetadataSource() {loadResourceDefine();}private void loadResourceDefine() {/*这里移动到DAO里面,信息从DB获取。 resourceMap = new HashMap<String, Collection<ConfigAttribute>>();Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();ConfigAttribute adminCA = new SecurityConfig("ROLE_ADMIN");atts.add(adminCA);ConfigAttribute userCA = new SecurityConfig("ROLE_USER");atts.add(userCA);resourceMap.put("/index.jsp", atts);*///resourceMap = authoritiesService.getResourceMap();//不明白这里怎么无法注入,难道因为这个filter在spring之前?????????IAuthoritiesService authoritiesService = (IAuthoritiesService)WebApplicationUtils.getApplicationContext().getBean("authoritiesService");resourceMap = authoritiesService.getResourceMap();System.out.println("-----> 载入资源:loadResourceDefine()");}// According to a URL, Find out permission configuration of this URL.public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {System.out.println("-----> 获得资源:getAttributes()");// guess object is a URL.String url = ((FilterInvocation) object).getRequestUrl();Iterator<String> ite = resourceMap.keySet().iterator();while (ite.hasNext()) {String resURL = ite.next();if (urlMatcher.pathMatchesUrl(url, resURL)) {return resourceMap.get(resURL);}}return null;}public boolean supports(Class<?> clazz) {return true;}public Collection<ConfigAttribute> getAllConfigAttributes() {return null;}}package com.security;import java.util.Collection;import java.util.Iterator;import org.springframework.security.access.AccessDecisionManager;import org.springframework.security.access.AccessDeniedException;import org.springframework.security.access.ConfigAttribute;import org.springframework.security.access.SecurityConfig;import org.springframework.security.authentication.InsufficientAuthenticationException;import org.springframework.security.core.Authentication;import org.springframework.security.core.GrantedAuthority;//<!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 -->public class MyAccessDecisionManager implements AccessDecisionManager {// In this method, need to compare authentication with configAttributes.// 1, A object is a URL, a filter was find permission configuration by this// URL, and pass to here.// 2, Check authentication has attribute in permission configuration// (configAttributes)// 3, If not match corresponding authentication, throw a// AccessDeniedException.public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {System.out.println("-----> 访问决策器,决定某个用户具有的角色," +"是否有足够的权限去访问某个资源["+object.toString()+"]");if (configAttributes == null) {return;}System.out.println("被访问资源URL="+object.toString()); // object is a URL.// configAttributes是含有访问url的所有权限// authentication.getAuthorities()用户的权限或者角色Iterator<ConfigAttribute> ite = configAttributes.iterator();while (ite.hasNext()) {ConfigAttribute ca = ite.next();String needRole = ((SecurityConfig) ca).getAttribute();//当url的所需权限,也是这个账户拥有的权限一样的时候,表示有权限,并返回。for (GrantedAuthority ga : authentication.getAuthorities()) {if (needRole.equals(ga.getAuthority())) { // ga is user's role.System.out.println("-----> 有访问权限,返回.");return;}}}//没有权限就抛出异常.throw new AccessDeniedException("没有访问权限.");}@Overridepublic boolean supports(ConfigAttribute attribute) {// TODO Auto-generated method stubreturn true;}@Overridepublic boolean supports(Class<?> clazz) {return true;}}package com.security;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import org.springframework.security.access.SecurityMetadataSource;import org.springframework.security.access.intercept.AbstractSecurityInterceptor;import org.springframework.security.access.intercept.InterceptorStatusToken;import org.springframework.security.web.FilterInvocation;import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;/*<!-- 一个自定义的filter, 必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性, 我们的所有控制将在这三个类中实现,解释详见具体配置 --> */public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptorimplements Filter {private FilterInvocationSecurityMetadataSource securityMetadataSource;/** * Method that is actually called by the filter chain. Simply delegates to * the {@link #invoke(FilterInvocation)} method. * * @param request, the servlet request * @param response, the servlet response * @param chain, the filter chain * * @throws IOException, if the filter chain fails * @throws ServletException,if the filter chain fails */public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("-----> 自定义的filter.doFilter()");FilterInvocation fi = new FilterInvocation(request, response, chain);invoke(fi);}public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {return this.securityMetadataSource;}public Class<? extends Object> getSecureObjectClass() {return FilterInvocation.class;}public void invoke(FilterInvocation fi) throws IOException, ServletException {System.out.println("-----> 自定义的filter.invoke()");InterceptorStatusToken token = super.beforeInvocation(fi);try {fi.getChain().doFilter(fi.getRequest(), fi.getResponse());} finally {super.afterInvocation(token, null);}}public SecurityMetadataSource obtainSecurityMetadataSource() {return this.securityMetadataSource;}public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource newSource) {this.securityMetadataSource = newSource;}@Overridepublic void destroy() {}@Overridepublic void init(FilterConfig arg0) throws ServletException {}}package com.security;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.dao.DataAccessException;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.GrantedAuthorityImpl;import org.springframework.security.core.userdetails.User;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import com.pojo.Roles;import com.pojo.Users;import com.pojo.UsersRoles;import com.service.IRolesService;import com.service.IUsersService;// <!-- 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 -->public class MyUserDetailService implements UserDetailsService {@Autowiredpublic IUsersService usersService;@Autowiredpublic IRolesService rolesService;@Overridepublic UserDetails loadUserByUsername(String username)throws UsernameNotFoundException, DataAccessException {Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();String password = null;System.out.println("-----> 载入用户的信息:loadUserByUsername()");/*if (username.equals("admin")) {password="admin";GrantedAuthorityImpl auth1 = new GrantedAuthorityImpl("ROLE_ADMIN");auths.add(auth1);System.out.println("-----> 设定用户角色[ROLE_ADMIN]:loadUserByUsername()");}*///获得登陆用户信息Users loginUser = usersService.getUserByUserName(username);if(loginUser!=null){password=loginUser.getPassword();if(loginUser.getUsersRoleses()!=null){//设定用户权限Iterator it = loginUser.getUsersRoleses().iterator();while(it.hasNext()){UsersRoles ur = (UsersRoles)it.next();Roles role = rolesService.getRolesById(ur.getId().getRoleId());GrantedAuthorityImpl auth1 = new GrantedAuthorityImpl(role.getName());auths.add(auth1);System.out.println("-----> 设定用户["+loginUser.getName()+"]角色["+role.getName()+"]:loadUserByUsername()");}}}// User(String username, String password, boolean enabled, boolean// accountNonExpired,// boolean credentialsNonExpired, boolean accountNonLocked,// Collection<GrantedAuthority> authorities) {User user = new User(username, password, true, true, true, true, auths);return user;}}<?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-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> <!-- 这里启动Service层方法保护 --> <global-method-security secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled"/> <http access-denied-page="/common/403.jsp"><!-- 当访问被拒绝时,会转到403.jsp --> <intercept-url pattern="/login.jsp" filters="none" /> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.jsp" /> <logout logout-success-url="/login.jsp" /> <http-basic /> <!-- 增加一个filter,这点与Acegi是不一样的,不能修改默认的filter了,这个filter位于FILTER_SECURITY_INTERCEPTOR之前 --> <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myFilter" /> </http> <!-- 一个自定义的filter,必须包含authenticationManager,accessDecisionManager,securityMetadataSource三个属性, 我们的所有控制将在这三个类中实现,解释详见具体配置 --> <beans:bean id="myFilter" ref="authenticationManager" /> <beans:property name="accessDecisionManager" ref="myAccessDecisionManagerBean" /> <beans:property name="securityMetadataSource" ref="securityMetadataSource" /> </beans:bean> <!-- 认证管理器,实现用户认证的入口,主要实现UserDetailsService接口即可 --> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="myUserDetailService"> <!-- 如果用户的密码采用加密的话,可以加点“盐” <password-encoder hash="md5" /> --> </authentication-provider> </authentication-manager> <beans:bean id="myUserDetailService" /> <!-- 访问决策器,决定某个用户具有的角色,是否有足够的权限去访问某个资源 --> <beans:bean id="myAccessDecisionManagerBean" /> </beans:beans>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>Login Page</title> </head> <body> <form name="f" action="j_spring_security_check" method="post"> UserName:<input type="text" id="j_username" name="j_username" value="admin"> <br> Password:<input type="password" id="j_password" name="j_password" value="admin"> <br> <input type="submit" value="Submit"> </form> </body></html>
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>Index</title> </head> <body> No Auth:<a href="./saveAndSearch.do">save And search</a> <br> <a href="./search1.do">@Secured Auth</a> <a href="./search2.do">@RolesAllowed Auth</a> <a href="./search3.do">@PreAuthorized Auth</a> <a href="./search4.do">@PostAuthorized Auth</a> <br> Admin Group:<a href="./pages/admin/index1_1.jsp">Admin 1</a> <a href="./pages/admin/index1_2.jsp">Admin 2</a> <a href="./pages/admin/index1_3.jsp">Admin 3</a> <a href="./pages/admin/index1_4.jsp">Admin 4</a> <a href="./pages/admin/index1_5.jsp">Admin 5</a> <br> User Group:<a href="./pages/user/index1_1.jsp">User 1</a> <a href="./pages/user/index1_2.jsp">User 2</a> <a href="./pages/user/index1_3.jsp">User 3</a> <a href="./pages/user/index1_4.jsp">User 4</a> <a href="./pages/user/index1_5.jsp">User 5</a> </body></html>1 楼 JOHN_226 2012-04-12 高手在民间