***************@Date("2018-5-6")***************
===知识点===
1、spring.xml中的bean id 要与web.xml中定义的过滤器名称一致
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"/>
和
<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>
PS:默认情况下,Spring会到IOC容器中查找<filter-name>对应的bean,
也可以在web.xml中通过targetBeanName的初始化参数来配置spring.xml中filter bean 的id
2、动态初始化资源和权限时采用第一次匹配优先的方式,所以顺序不能随便摆放
3、未登录情况下,如果访问需认证的页面或需授权的页面,则会自动跳转到loginUrl对应的地址;
已登陆情况下,如果访问需授权的页面,则会自动跳转到unauthorizedUrl对应的地址;
4、盐值加密:即使两个人的原始密码一样,加密后也不一样;一般是通过用户名或随机数生成salt进行加密
5、认证策略(AbstractAuthenticationStrategy类)一共有三种,默认为AtLeastOneSuccessfulStrategy
6、配置realm
<bean id="jdbcRealm" class="com.syjp.shiro.realms.ShiroRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property><!--加密哈希算法名称-->
<property name="hashIterations" value="1024"></property><!--加密迭代次数,加密多少次-->
</bean>
</property>
</bean>
<bean id="secondRealm" class="com.syjp.shiro.realms.SecondRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="Sha1"></property>
<property name="hashIterations" value="1024"></property>
</bean>
</property>
</bean>
底层加密算法:
Object result = new SimpleHash(hashAlgorithmName, credentials, salt,hashIterations);
普通验证:
AuthenticationInfo info=new SimpleAccount(principals, credentials,realmName);
盐值加密验证:
AuthenticationInfo info = new SimpleAccount(principals, credentials, salt,realmName);
计算盐值方法:
ByteSource salt = ByteSource.Util.bytes(principals);
PS: 形参realmName就是当前realm对应的name,调用父类的getName()方法即可
7、realms可以直接在securityManager中配置,也可以在authenticator中配置
8、配置记住我cookie过期时间
在securityManager中配置以下属性,单位为秒,默认过期时间为1年,
<property name="rememberMeManager.cookie.maxAge" value="6"></property>
9、如果配置了CacheManager,那么在登陆第一次后,再次登陆shiro就会从还从里面取出用户信息进行比较,所以不会执行认证方法。
10、登出可以通过自定义的方法,也可以通过shiro的登出过滤器去配置(有两种办法)
第一种(推荐):
<bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter">
<property name="redirectUrl" value="/list.jsp" />
</bean>
和在shiroFilter中配置
/shiro/logout = logout (登出的URL地址(随便写),登出过滤器的bean id)
参考博客:
http://dwangel.iteye.com/blog/1890524
https://blog.csdn.net/qq_34292044/article/details/79131199
11、动态初始化资源和权限
<!-- 通过实例工厂的方式配置Bean -->
<bean id="filterChainDefinitionMap" factory-bean="filterChainDefinitionMapBuilder" factory-method="buildFilterChainDefinitionMap"></bean>
<bean id="filterChainDefinitionMapBuilder" class="com.syjp.shiro.factory.FilterChainDefinitionMapBuilder"> </bean>
和在shiroFilter中配置
<property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>
和自定义类
public class FilterChainDefinitionMapBuilder {
public LinkedHashMap<String, String> buildFilterChainDefinitionMap() {
// 由于权限有先后顺序之分,所以得用LinkedHashMap(先进先出)
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("/login.jsp", "anon");
map.put("/login", "anon");
map.put("/index.jsp", "anon");
map.put("/admin.jsp", "roles[admin]");
map.put("/user.jsp", "authc,roles[user]");// authc 必须经过验证,如果配置了/**则没有必要写了
//map.put("/list.jsp", "user");// user 代表可以通过记住我进行访问
map.put("/list.jsp", "roles[admin]");//供登出成功调用
map.put("/shiro/logoutzzzz", "logout");//键值(即登出的对应地址)随便写
map.put("/**", "authc");
return map;
}
}
12、通过记住我登陆
在登陆方法中配置,
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
token.setRememberMe(true);
在权限配置中添加
map.put("/list.jsp", "user");// user 代表可以通过记住我进行访问
13、进行授权操作,需要继承AuthorizingRealm类,实现其中的授权和认证两个方法
===问题(已解决)===
1、Shiro的 @RequiresRoles注解不生效
网上搜的时候这俩bean是在一起的,LifecycleBeanPostProcessor 是管理shiro生命周期的,不直接跟权限注解关联。
所以加上DefaultAdvisorAutoProxyCreator 这个bean就可以了。
/* @Bean
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}*/
@Bean
public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){
return new DefaultAdvisorAutoProxyCreator();
}
参考博客:https://blog.csdn.net/qq_35981283/article/details/78631924
===问题(未解决)===
1、所有页面(login.jsp)中的${request.contextPath}都解析不出来
2、在缓存失效之前进入一个页面,如果不关闭浏览器,那么就可以一直访问该页面(即使添加随机数)