自定义了一个表单fileter以及一个realm。登陆请求能被fileter拦截,但是总是不进入realm.
fileter:
public class CustomFromAuthenticationFilter extends FormAuthenticationFilter
{
    @Override
    protected boolean onAccessDenied(ServletRequest request,ServletResponse response) throws Exception {
     System.out.println("1");
        //在这里进行验证码的校验
        HttpServletRequest httpServletRequest= (HttpServletRequest) request;
        HttpSession session=httpServletRequest.getSession();
        //取出session中的正确验证码
        String validateCode= (String) session.getAttribute("validateCode");
        //取出页面的验证码
        String randomcode=httpServletRequest.getParameter("randomcode");
        if (randomcode!=null&&validateCode!=null&&!randomcode.equals(validateCode))
        {
            //如果校验失败,将验证码错误的失败信息,通过shiroLoginFailure设置到request中
            httpServletRequest.setAttribute("shiroLoginFailure","randomCodeError");            //拒绝访问,不再校验账号和密码
            return true;        }
        return super.onAccessDenied(request, response);
    }
}spring-shiro.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:util="http://www.springframework.org/schema/util"  
       xmlns:aop="http://www.springframework.org/schema/aop"  
       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.xsd  
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd  
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">  
       <!--web.xml中shiro的filter对应的bean-->
    <!-- Shiro 的Web过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <!-- loginUrl认证提交地址,如果没有认证将会请求此地址进行认证,请求此地址将由formAuthenticationFilter进行表单认证 -->
        <property name="loginUrl" value="/testController/login.do"/>
        <!--认证成功统一跳转到first.actio,建议不配置,不配置的话shiro认证成功会自动到上一个请求路径-->
       <!-- <property name="successUrl" value="/testController/success.do"/> -->
        <property name="unauthorizedUrl" value="/refuse.html" />        <!--自定义filter-->
        <property name="filters">
            <map>
                <!-- 将自定义的FormAuthenticationFilter注入shiroFiler中 -->
                <entry key="authc" value-ref="formAuthenticationFilter" />
            </map>
        </property>        <!-- 过虑器链定义,从上向下顺序执行,一般将/**放在最下边 -->
        <property name="filterChainDefinitions">
            <value>
                <!--设置静态资源可以直接访问-->
/view/css/**=anon
/view/imgs/**=anon
/view/js/**=anon
/view/html/login.html=anon
                <!--请求这个地址就自动退出-->
                /testController/logout.do=logout
                <!--商品查询需要商品查询权限,取消url拦截配置,采用注解授权-->
                <!--/items/queryItems.action=perms[item:query]-->
                <!--&lt;!&ndash;商品修改需要商品修改权限&ndash;&gt;-->
                <!--/items/editItems.action=perms[item:edit]-->                <!--配置记住我或认证通过可以访问的地址-->                <!-- -/**=authc 表示所有的url都必须认证通过才可以访问- -->
                 /**= authc
                <!--/**=anon 表示所有的url都可以匿名访问-->            </value>
        </property>
    </bean>    <!--securityManage-->
    <!-- 安全管理器 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="customRealm" />        <!--注入缓存管理器-->
        <!-- <property name="cacheManager" ref="cacheManager"/> -->        <!--注入会话管理器-->
        <!-- <property name="sessionManager" ref="sessionManager" /> -->        <!-- 记住我 -->
      <!--   <property name="rememberMeManager" ref="rememberMeManager"/> -->
    </bean>    <!--自定义realm-->
    <bean id="customRealm" class="com.web.ssm.shiro.CustomRealm">
        <!--将凭证匹配器设置到realm中,realm按照凭证匹配器要求进行散列-->
        <property name="credentialsMatcher" ref="credentialsMatcher"/>
    </bean>    <!-- 凭证匹配器 -->
    <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="md5" />
        <property name="hashIterations" value="1" />
    </bean>    <!-- 缓存管理器 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
    </bean>
    <!-- 会话管理器 -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- session的失效时长,单位毫秒 -->
        <property name="globalSessionTimeout" value="600000"/>
        <!-- 删除失效的session -->
        <property name="deleteInvalidSessions" value="true"/>
    </bean>
    <!--自定义form认证过滤器-->
    <bean id="formAuthenticationFilter" class="com.web.ssm.shiro.CustomFromAuthenticationFilter">
        <!-- 表单中账号的input名称 -->
        <property name="usernameParam" value="username" />
        <!-- 表单中密码的input名称 -->
        <property name="passwordParam" value="password" />
        <!--记住我input的名称-->
       <!--  <property name="rememberMeParam" value="rememberMe"/> -->
    </bean>    <!-- rememberMeManager管理器 -->
    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
        <property name="cookie" ref="rememberMeCookie" />
    </bean>
    <!-- 记住我cookie -->
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!--rememberMe时cookie的名字-->
        <constructor-arg value="rememberMe" />
        <!-- 记住我cookie生效时间30天 -->
        <property name="maxAge" value="2592000" />
    </bean>
</beans> 
自定义realm:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
 //token是用户输入的
        //第一步:丛token中取出身份信息
        String userCode= (String) token.getPrincipal();
        String pass=MD5Util.md5Pwd("123456");
        System.out.println("2");
       
        SimpleAuthenticationInfo simpleAuthenticationInfo=new
                SimpleAuthenticationInfo(userCode,pass,this.getName());
        return simpleAuthenticationInfo;
}
controller:
@RequestMapping(value="/login")
    public String login(HttpServletRequest request,HttpServletResponse response, Model model) throws Exception{
//如果登录失败从request中获取认证异常信息,shiroLoginFailure就是shiro异常类的全限定名
        String exceptionClassName= (String) request.getAttribute("shiroLoginFailure");
        System.out.println("3");
        //根据shiro返回的异常类路径判断,抛出指定异常信息
        if(exceptionClassName!=null){
            if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
                //最终会抛给异常处理器
                request.setAttribute("error", "账号不存在");
            } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
             request.setAttribute("error", "用户名/密码错误");
            } else if("randomCodeError".equals(exceptionClassName)){
             request.setAttribute("error", "用户名/密码错误");
            } else{
                throw new Exception();//最终在异常处理器生成未知错误
            }
        }        //此方法不处理登录成功,shiro认证成功会自动跳转到上一个路径        //登录失败返回到login页面
        return "login";
    }login.html:
<body>
   <div class="main">
   <h1 class="lean">Login</h1>
   <form class="form-horizontal" role="form" id="default-form" action="testController/login.do" method="post">
   <div class="form-group">
   <label for="username" class="col-sm-2 control-label">
   <span class="glyphicon glyphicon-user"></span>
   </label>
   <div class="col-sm-9">
      <input type="text" class="form-control" name="username" id="username" placeholder="Username">
    </div>
    </div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">
   <span class="glyphicon glyphicon-lock"></span>
   </label>
<div class="col-sm-9">
      <input type="password" class="form-control" id="password" name="password" placeholder="Password">
     <span class="help-block" th:text="${error}">dfasffadsfas</span>
    </div>
   </div>
   <div class="form-group">
    <div class="col-sm-offset-2 col-sm-9">
      <div class="checkbox">
        <label>
          <input type="checkbox">Remember
        </label>
        <label style="display: inline-block;float:right;">Go register</label>
      </div>
    </div>
</div>
   <button type="submit" class="log-btn btn-danger btn-radius"><span class="glyphicon glyphicon-chevron-right"></span></button>
   </form>
</div>
</body>

解决方案 »

  1.   

    大概看了一眼,应该是你的controller不对
    Controller的login方法
    应该有这么一句:
    UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPwd());
                    token.setRememberMe(user.isRemenber());
                    SecurityUtils.getSubject().login(token);
      

  2.   

    好像不是这样的,方式不一样,我参考的教程就是这样写的。它的controller里边没做你的那种处理。