原文地址:http://blog.csdn.net/zcl_love_wx
注意:此文是基于springMVC框架的,所以关于springMVC的配置这里不说,后面有时间专门写一个shiro整合spring的文章
1.shiro表单认证流程
2.shiro认证代码
2.1 页面代码
这里的method值必须为post,否则不会执行认证过程而直接执行在spring.xml里配置的loginUrl指定的路径
<form action="<%=basePath%>login.do" method="post">
username:<input type="text" name="username"><p>
password:<input type="password" name="password">
<p>${msg}
<input type="submit" value="submit">
</form>
2.2 web.xml文件需要添加的代码
<filter-name>
标签里的过滤器名字,应与spring.xml里配置的过滤器名一致
<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>
2.3 控制器代码
realm 认证不通过时,会将错误信息添加到request中,这样在下面的方法中,可通过shiroLoginFailure这个键获取到错误信息的类名。
// 用户登陆提交
@RequestMapping("/login.do")
public String loginsubmit(HttpServletRequest request,Model model)
throws Exception {
// shiro在认证过程中出现错误后将异常类路径通过request返回
String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
if(exceptionClassName!=null){
if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
System.out.println("账号不存在");
} else if (IncorrectCredentialsException.class.getName().equals(
exceptionClassName)) {
System.out.println("用户名/密码错误");
} else if("randomCodeError".equals(exceptionClassName)){
System.out.println("验证码错误");
} else{
System.out.println("未知错误");
}
}
return "/login.jsp";
}
2.3 自定义realm的代码
/****
* 自定义Realm
*
* @author Peter
* @date 2016-06-03
*
*/
public class MyShiroRealm extends AuthorizingRealm {
@Override
public String getName() {
return"customRealm";
}
// 支持什么类型的token
@Override
public boolean supports(AuthenticationToken token) {
return token instanceof UsernamePasswordToken;
}
/***
* 获取授权信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
//省略......
return null;
}
/***
* 获取认证信息
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) {
UsernamePasswordToken token = (UsernamePasswordToken) at; //这里也有用户名与密码
// 接收表单的用户名
String username = (String) at.getPrincipal();
if (username != null && !"".equals(username)) {
//通过用户名去数据查回用户操作
//省略......
//模拟数据库查加的用户名为:"张春玲",密码为:"123456"
if("张春玲".equals(username) && "123456".equals(token.getUsername())){
}else{
throw new IncorrectCredentialsException(); //抛出密码错误异常
}
} else{
throw new UnknownAccountException(); //没有该用户异常
}
return null;
}
}
2.4 spring.xml需要添加的代码
注意,loginUrl指定的路径必须是authc(即认证通过才可访问),否则请求不会被realm拦截而直接执行了loginUrl指定的路径
<!-- Shiro的Web过滤器 -->
<!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
<!-- successUrl可配置登录成功后的跳转路径,如果不配的话,就自动跳转到请求登录时的路径,即上一个路径。所以建议不配 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<property name="loginUrl" value="/login.do"/>
<property name="unauthorizedUrl" value="/refuse.jsp"/>
<!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
<property name="filterChainDefinitions">
<value>
/login.do = authc<!-- 登录的地址必须是authc,不然也不会执行realm而直接执行登录路径了 -->
/** = authc <!-- user表示身份认证通过或通过记住我认证通过的可以访问 -->
</value>
</property>
</bean>
<!-- 注入 -->
<bean id="myShiroRealm" class="com.mvc.realm.MyShiroRealm"> </bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myShiroRealm"></property>
</bean>