1、准备Shiro的架包和spring 的架包
2、项目的架构
3、配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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_2_5.xsd"> <display-name>simpleSpringMCV</display-name> <!-- 加载文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext-shiro.xml </param-value> </context-param> <!-- shiro --> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 加载springmvc --> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 以.htm结尾的都被mvc拦截 --> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> <!-- 启动spring 加载 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" 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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd">
	
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="successUrl" value="/member/index.htm" />
		<property name="loginUrl" value="/login.htm" />
		<property name="unauthorizedUrl" value="/error.htm" />
		<property name="filters">
			<map>
				<entry key="authc" value-ref="shiro"></entry>
			</map>
		</property>
		<property name="filterChainDefinitions">
			<value>
				/login.htm=anon
				/submit.htm=anon
				/error.htm=anon
				/member/**=authc,roles["member"]
            </value>
		</property>
	</bean>
	<bean id="shiro" class="com.cat.shiro.ShiroFilter">
	</bean>
	<bean id="shiroRealm" class="com.cat.shiro.ShiroRealm" />
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="shiroRealm" />
		<!-- 需要使用cache的话加上这句
		<property name="cacheManager" ref="shiroEhcacheManager" />
		 -->
	</bean>
	<!-- 用户授权信息Cache, 采用EhCache,需要的话就配置上此信息 
	<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
		<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />
	</bean>
	-->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
	<bean
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
		depends-on="lifecycleBeanPostProcessor">
		<property name="proxyTargetClass" value="true" />
	</bean>
	<bean
		class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" />
	</bean>
</beans>5、配置mvc.xml
<?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:p="http://www.springframework.org/schema/p" 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"> <mvc:annotation-driven/> <!-- 自动扫描包 --> <context:component-scan base-package="com.cat.spring.controller" /> <!-- mvc返回页面的配置 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 模板路径为WEB-INF/pages/ --> <property name="prefix"> <value>/WEB-INF/pages/</value> </property> <!-- 视图模板后缀为.JSP --> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans>
6、创建ShiroFilter和ShiroRealm
ShiroFilter.java
/**
 * 
 */
package com.cat.shiro;
import java.io.IOException;
import java.security.Principal;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import com.cat.spring.entity.Role;
import com.cat.spring.entity.User;
/**
 * @author chenlf
 * 
 *         2014-3-24
 */
public class ShiroFilter implements Filter {
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		Principal principal = httpRequest.getUserPrincipal();
		if (principal != null) {
			Subject subjects = SecurityUtils.getSubject();
			// 为了简单,这里初始化一个用户。实际项目项目中应该去数据库里通过名字取用户:
			// 例如:User user = userService.getByAccount(principal.getName());
			User user = new User();
			user.setName("shiro");
			user.setPassword("123456");
			user.setRole(new Role("member"));
			if (user.getName().equals(principal.getName())) {
				UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user
						.getPassword());
				subjects = SecurityUtils.getSubject();
				subjects.login(token);
				subjects.getSession();
			} else {
				// 如果用户为空,则subjects信息登出
				if (subjects != null) {
					subjects.logout();
				}
			}
		}
		chain.doFilter(httpRequest, httpResponse);
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
	}
}
ShiroRealm.java
/**
 * 
 */
package com.cat.shiro;
import java.util.ArrayList;
import java.util.List;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import com.cat.spring.entity.Role;
import com.cat.spring.entity.User;
/**
 * @author chenlf
 * 
 *         2014-3-24
 */
public class ShiroRealm extends AuthorizingRealm {
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// 根据用户配置用户与权限
		if (principals == null) {
			throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
		}
		String name = (String) getAvailablePrincipal(principals);
		List<String> roles = new ArrayList<String>();
		// 简单默认一个用户与角色,实际项目应User user = userService.getByAccount(name);
		User user = new User("shiro", "123456");
		Role role = new Role("member");
		user.setRole(role);
		if (user.getName().equals(name)) {
			if (user.getRole() != null) {
				roles.add(user.getRole().getName());
			}
		} else {
			throw new AuthorizationException();
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		// 增加角色
		info.addRoles(roles);
		return info;
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		// 简单默认一个用户,实际项目应User user = userService.getByAccount(token.getUsername());
		User user = new User("shiro", "123456");
		if (user == null) {
			throw new AuthorizationException();
		}
		SimpleAuthenticationInfo info = null;
		if (user.getName().equals(token.getUsername())) {
			info = new SimpleAuthenticationInfo(user.getName(), user.getPassword(), getName());
		}
		return info;
	}
}
LoginController.java
/**
 * 
 */
package com.cat.spring.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.cat.spring.entity.Role;
import com.cat.spring.entity.User;
/**
 * @author chenlf
 * 
 *         2014-3-24
 */
@Controller
public class LoginController {
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public ModelAndView login() {
		return new ModelAndView("/login");
	}
	@RequestMapping(value = "/submit", method = RequestMethod.POST)
	public ModelAndView submit(String username, String password) {
		User user = new User("shiro", "123456");
		user.setRole(new Role("member"));
		try {
			// 如果登陆成功
			if (user.getName().equals(username) && user.getPassword().equals(password)) {
				UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user
						.getPassword().toString());
				Subject subject = SecurityUtils.getSubject();
				subject.login(token);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new ModelAndView("redirect:/member/index.htm");
	}
}
IndexController.java
/**
 * 
 */
package com.cat.spring.controller.member;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
/**
 * @author chenlf
 * 
 *         2014-3-24
 */
@Controller
@RequestMapping(value = "/member")
//会员中心要被拦截
public class IndexController {
	// 拦截/index.htm 方法为GET的请求
	@RequestMapping(value = "/index", method = RequestMethod.GET)
	public ModelAndView index() {
		ModelAndView view = new ModelAndView();
		view.setViewName("/member/index");
		return view;
	}
}
9、来看看效果图吧
没有登陆状态的访问/member/**被shiro拦截到登入界面
当用户(角色为member)为shiro 密码为123456时 再次登入/member/index.htm时就不会跳转到login界面了
10、附下源代码地址
【Shiro + Spring MVC整合】教程——权限控制,布布扣,bubuko.com
【Shiro + Spring MVC整合】教程——权限控制
原文:http://blog.csdn.net/xkafei/article/details/21879209