您的位置:首页 > 编程语言 > Java开发

Spring-mvc与shiro配置遇到的问题

2016-09-04 10:38 363 查看
第一次在项目里使用shiro,网上也搜到很多教程,然而我还是踩了两个坑。

第一个是验证失败,后来发现是数据库存的密码是md5加密的,从网上搜到的教程里有这样的一段配置:

<bean id="credentialsMatcher"
class="com.zlms.realm.RetryLimitHashedCredentialsMatcher">
<constructor-arg ref="cacheManager" />
<property name="hashAlgorithmName" value="md5" />
<property name="hashIterations" value="1" />
<property name="storedCredentialsHexEncoded" value="true" />
<!-- 最多尝试次数 默认 5 次 -->
<property name="maxCount" value="3" />
</bean>


然后就想当然的以为它会帮我进行加密以后验证,但是没有生效,不知为何而。

手动加上这段代码:

UsernamePasswordToken token = new UsernamePasswordToken(username, MD5Util.getMD5(password), remember);


验证就通过了。

第二个是登录成功跳转的页面仍然被拦截,还需要登录,但是我明明已经登录了。从这段代码:

Subject subject = SecurityUtils.getSubject();
subject.login(token);
System.out.println("subject " + subject.isAuthenticated());
System.out.println("remember " + subject.isRemembered());
System.out.println("user " + subject.getPrincipal());


输出为:

subject true
remember false
user admin


应该也没问题。

过滤链我是这样配置的

<property name="filterChainDefinitions">
<value>
/static/** = anon
/unauthorized = anon
/login = anon
/logout = logout
/admin/** =user
</value>
</property>


当我把user换成anon,跳转就成功了,但是就达不到拦截管理页面的目的了。因此问题一定出在身份验证里。

我又加了一个过滤器

<bean id="userFilter"
class="com.zlms.realm.MyUserFilter">
</bean>


<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login" />
<property name="unauthorizedUrl" value="/loginl" />
<property name="filters">
<util:map>
<entry key="authc" value-ref="formAuthenticationFilter" />
<entry key="user" value-ref="userFilter" />
</util:map>
</property>
<property name="filterChainDefinitions">
<value>
/static/** = anon
/unauthorized = anon
/login = anon
/logout = logout
/admin/** =user
</value>
</property>
</bean>


在MyUserFilter中:

@Override
protected boolean isAccessAllowed(ServletRequest arg0, ServletResponse arg1, Object arg2) {
// TODO Auto-generated method stub
boolean isAllowed=super.isAccessAllowed(arg0, arg1, arg2);
Subject subject = SecurityUtils.getSubject();
System.out.println("allow  principal "+subject.getPrincipal());
System.out.println("allow sub "+subject.isAuthenticated());
System.out.println("allow principals "+subject.getPrincipals());
return isAllowed;
}


输出如下

allow  principal null
allow sub false
allow principals null


表示这里Subject和登录时的Subject不是同一个,或者内容被清空。

最后在检查web.xml时发现我的配置是

<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>/admin/*</url-pattern>
</filter-mapping>


尝试把
<url-pattern>/admin/*</url-pattern>
修改为

<url-pattern>/*</url-pattern>


再一测试,竟然神奇的解决了那个困扰我三个小时的bug。

最后推测出现这种问题的原因。

由于我想把管理页面与前台页面分开,前台不需要做拦截,但是也有登录的功能,所以登录页面的路径设置为/login,后台页面的路径设置为/admin/*。然后我就想当然的在web.xml里设置成了

<url-pattern>/admin/*</url-pattern>


目的是只拦截后台页面。实际上这样会导致访问/login和/admin时subject不一致。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shiro subject 密码