第一步:引入shiro框架相关的jar
<!-- shiro框架依赖 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.2.2</version>
</dependency>
第二步:在web.xml中配置spring框架提供的用于整合shiro框架的过滤器
<!-- 配置shiro框架过滤器,用于整合spring -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
第三步:在spring配置文件中配置bean,id为shiroFilter
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/s`chema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 配置shiro框架的工厂对象 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入安全管理器对象 -->
<property name="securityManager" ref="securityManager"/>
<!-- 注入没有登录时访问的url -->
<property name="loginUrl" value="/login.jsp"/>
<!-- 注入权限不足时访问的url页面 -->
<property name="unauthorizedUrl" value="/unauthorized.jsp"/>
<property name="successUrl" value="/index.jsp"/>
<!-- 设置url拦截规则 -->
<property name="filterChainDefinitions" >
<value>
/css/**=anon <!-- 匿名访问过滤器 -->
/js/**=anon
/images/**=anon
/validatecode.jsp=anon
/login.jsp*=anon
/useraction_login.action=anon
<!-- 检测当前用户是否具有oldman/edit权限,权限不足跳转到"/unauthorized.jsp" -->
/page_recept_oldman=perms["oldman/edit"]
/*=authc <!-- 过滤器的作用是检测用户是否登录 -->
</value>
</property>
</bean>
<!-- 注入安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"></bean>
</beans>
此时当我们通过输入密码通过登录页面后,访问index页面,重新访问login.jsp,说明当前用户没有登录,所以要在login中重新编写shiro框架为我们提供的认证方法
//使用是shiro框架提供的方法进行权限认证
@RequestMapping("useraction_login.action")
public String login(HttpSession httpSession,User user,String checkcode,Model model){
//从session中获得生成的验证码
String validatecode = (String) httpSession.getAttribute("key");
if(StringUtils.isNotBlank(checkcode) && checkcode.equals(validatecode)){
Subject subject = SecurityUtils.getSubject();//获得当前用户对象,"状态为未认证"
AuthenticationToken token = new UsernamePasswordToken(user.getUsername(),MD5Utils.md5(user.getPassword()));//创建用户名密码令牌对象
try {
subject.login(token);//这里会默认调用安全管理器
user = (User) subject.getPrincipal();
//登录成功,将user对象放入session,跳转到首页
httpSession.setAttribute("loginUser", user);
return "pages/common/index";
} catch (Exception e) {
//登录失败,,设置提示信息,跳转到登录页面
//输入的验证码错误,设置提示信息,跳转到登录页面
model.addAttribute("message", "用户名或者密码输入错误!");
return "login";
}
}else{
//输入的验证码错误,设置提示信息,跳转到登录页面
model.addAttribute("message", "输入的验证码错误!!");
return "login";
}
}
subject.login(token);//这里会默认调用安全管理器,安全管理器接着调用realm
第五步:注入realm
<!-- 注入安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="restHomeRealm"/>
</bean>
<!-- 注册realm -->
<bean id="restHomeRealm" class="com.resthome.realm.ResthomeRealm"></bean>
第六步:自定义realm
这里可以实现realm接口但是里面方法太多,可以选择继承realm的子类
public class ResthomeRealm extends AuthorizingRealm{
@Autowired
private UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken passwordToken = (UsernamePasswordToken) token;
//获得页面输入的用户名
String username = passwordToken.getUsername();
//根据用户名查询数据库中的密码
User user = userService.findUserByUsername(username);
if (user==null) {
return null;
}
//框架负责比对数据库中的密码和页面中的密码是否一致
//user被绑定到threadload本地线程
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(),this.getName());
return info;
}
}