易用宝项目记录day5-shiro
1.shiro的认识
-
shiro是一个权限框架
-
shiro和Spring security区别
-
shiro更加易用 属于粗粒度
-
Spring security比较复杂难学 但是属于细粒度 权限控制更好
-
2.shiro的四大基石
身份验证、授权、密码学和会话管理
securityManager:核心对象 realm:获取数据接口
3.配置web.xml
主页:shiro的过滤器是很重要的,过滤请求达到限制权限的目的
<!--
shiro的过滤器 所有请求都要过滤
Delegating(委托)FilterProxy(代理)
shiroFilter:这个名称非常重要
-->
<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>/*</url-pattern>
</filter-mapping>
4.配置application-shiro.xml
在applicationContext.xml 里面引入applicationContext-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd">
<!-- 真假过滤器(shiroFilter),安全管理器(securityManager),AiSellRealm(自定义realm),注解支持 -->
<!--
DefaultWebSecurityManager:创建Shiro的核心对象
相当于: SecurityManager sm = new DefaultWebSecurityManager(myRealm);
-->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="jdbcRealm"/>
</bean>
<!-- 等会需要改成自己的Realm -->
<bean id="jdbcRealm" class="cn.xiaji.web.shiro.AISellRealm">
<!--密码的匹配器-->
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"/>
<property name="hashIterations" value="1000"/>
</bean>
</property>
</bean>
<!-- 这三个留着,你的权限就可以支持注解功能 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
<!--
这个是真正的shiro过滤器
要求:这个id的名称必需和web.xml中的那个过滤器名称一致
-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<!-- 登录地址:如果你没有登录,就会去这个地方 -->
<property name="loginUrl" value="/login"/>
<!-- 登录成功会进入的页面 -->
<property name="successUrl" value="/main.jsp"/>
<!-- 没有权限进入的页面 -->
<property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
<!--
路径 = anon -> 没有登录也可以访问这个路径
/** = authc -> 所有路径都要权限拦截
-->
<!--<property name="filterChainDefinitions">
<value>
/s/login.jsp = anon
/employee/index = perms[employee:index]
/login =anon
/** = authc
</value>
</property>-->
<property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"/>
</bean>
<!--实体工厂bean,把它返回值也变成一个bean-->
<bean id="filterChainDefinitionMap" factory-bean="filterChainDefinitionMapFactory"
factory-method="builderFilterChainDefinitionMap"/>
<!-- 拿到生成map的工厂 -->
<bean id="filterChainDefinitionMapFactory" class="cn.xiaji.web.shiro.FilterChainDefinitionMapFactory"/>
</beans>
5.配置FilterChainDefinitionMapFactory 放行需要放行的文件
注意:返回的Map必需是有序的(LinkedHashMap)
package cn.xiaji.web.shiro;
//encoding: utf-8
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author: xj
* @contact: xiaruji520@gmail.com
* @file: FilterChainDefinitionMapFactory.java
*/
/*
*/
public class FilterChainDefinitionMapFactory {
public Map<String, String> builderFilterChainDefinitionMap() {
Map<String, String> maps = new LinkedHashMap<>();
//maps中加数据
//设置放行
maps.put("/s/*", "anon");
maps.put("/login", "anon");
maps.put("/easyui/**", "anon");
maps.put("/js/**", "anon");
maps.put("/json/**", "anon");
maps.put("/css/**", "anon");
maps.put("*.js", "anon");
maps.put("*.css", "anon");
maps.put("/images/**", "anon");
//设置权限拦截
maps.put("/employee/index", "perms[employee:index]");
maps.put("/dept/index", "perms[dept:index]");
//设置拦截所有
maps.put("/**", "authc");
return maps;
}
}
6.自定义Realm
继承AuthorizingRealm,覆写下面两个方法
//进行授权判断(权限)
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//1.拿到当前登录的用户
String username = (String) principalCollection.getPrimaryPrincipal();
//2.根据登录用户拿到角色与权限
Set<String> roles = getRoles(username);
Set<String> permissions = getPermissions(username);
//3.创建返回的权限对象
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//把角色放到权限对象中去
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
//根据用户名拿到角色
public Set<String> getRoles(String username) {
Set<String> roles = new HashSet<String>();
roles.add("admin");
roles.add("root");
return roles;
}
//根据用户名拿到权限
public Set<String> getPermissions(String username) {
Set<String> perms = new HashSet<String>();
perms.add("employee:*");
perms.add("dept:index");
return perms;
}
//登录验证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1.拿令牌(拿对应的用户名)
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//2.根据用户名取拿密码
String username = token.getUsername();
Employee loginUser = employeeService.findByUsername(username);
if (loginUser == null) {
//返回null为:用户名错误
return null;
}
//获取到盐值
ByteSource salt = ByteSource.Util.bytes("xiaji");
//getName():只是随便起的名
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, loginUser.getPassword(), salt, getName());
return authenticationInfo;
}