1:配置pom.xml
1 <!--导入shiro包-->
2 <dependency>
3 <groupId>org.apache.shiro</groupId>
4 <artifactId>shiro-all</artifactId>
5 <version>1.4.0</version>
6 </dependency>
7 <!--导入shiro-spring-->
8 <dependency>
9 <groupId>org.apache.shiro</groupId>
10 <artifactId>shiro-spring</artifactId>
11 <version>1.4.0</version>
12 </dependency>
知识兔2:web.xml中的配置
1 <!-- shiro的过滤器(帮我们拦截请求)-》什么事情都不做
2 Delegating:授(权); 把(工作、权力等)委托(给下级); 选派(某人做某事)
3 Proxy:代理 -> 需要通过名称(shiroFilter)去找真正的过滤器
4 -->
5 <filter>
6 <filter-name>shiroFilter</filter-name>
7 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
8 <init-param>
9 <param-name>targetFilterLifecycle</param-name>
10 <param-value>true</param-value>
11 </init-param>
12 </filter>
13 <filter-mapping>
14 <filter-name>shiroFilter</filter-name>
15 <url-pattern>/*</url-pattern>
16 </filter-mapping>
知识兔3:配置applictionContest-shiro.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="
5 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
6 <!--
7 Shiro的核心对象(权限管理器)
8 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
9 securityManager.setRealm(jpaRealm)
10 -->
11 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
12 <property name="realm" ref="jpaRealm"/>
13 </bean>
14 <!--
15 JpaRealm jpaRealm = new JpaRealm();
16 配置咱们的自定义realm
17 -->
18 <bean id="jpaRealm" class="com.logo.aisell.web.shiro.JpaRealm">
19 <!--Realm的名称-->
20 <property name="name" value="jpaRealm"/>
21 <property name="credentialsMatcher">
22 <!-- 配置哈希密码匹配器 -->
23 <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
24 <!--加密方式:MD5-->
25 <property name="hashAlgorithmName" value="MD5"/>
26 <!--迭代次数-->
27 <property name="hashIterations" value="10" />
28 </bean>
29 </property>
30 </bean>
31 <!-- 这三个配置好,可以支持注解权限 -->
32 <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
33 <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
34 depends-on="lifecycleBeanPostProcessor"/>
35 <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
36 <property name="securityManager" ref="securityManager"/>
37 </bean>
38 <!--
39 shiro真正的过滤器(功能就是它完成的)
40 这个bean的名称必需和web.xml里的的代理过滤器名字相同
41 -->
42 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
43 <!--必需要用到权限管理器-->
44 <property name="securityManager" ref="securityManager"/>
45 <!--如果你没有登录,你会进入这个页面-->
46 <property name="loginUrl" value="/login"/>
47 <!--登录成功后,进入的页面(一般没什么用)-->
48 <property name="successUrl" value="/main"/>
49 <!--如果你没有权限,你会进入这个页面-->
50 <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
51 <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap" />
52 <property name="filters">
53 <map>
54 <entry key="aiSellPerms" value-ref="aiSellPermissionsAuthorizationFilter"></entry>
55 </map>
56 </property>
57 </bean>
58
59 <!--拿到shiroFilterMapFactory里面的createMap方法的值 -->
60 <bean id="filterChainDefinitionMap" factory-bean="shiroFilterMapFactory" factory-method="creatMap" />
61 <bean id="shiroFilterMapFactory" class="com.logo.aisell.web.shiro.ShiroFilterMapFactory"/>
62 <!--配置我们的自定义权限过滤器-->
63 <bean id="aiSellPermissionsAuthorizationFilter"
64 class="com.logo.aisell.web.shiro.AiSellPremissiAuthorizationFilter">
65 </bean>
66 </beans>
知识兔4:配置applictionContext.xml
<import resource="classpath:applicationContext-shiro.xml" />
知识兔5:准备自定义Realm 用于做身份认证和权限
1 public class JpaRealm extends AuthorizingRealm {
2 @Autowired
3 private IEmployeeService employeeService;
4 @Autowired
5 private IPermissionService permissionService;
6
7 @Override//授权
8 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
9 //拿到授权对象
10 SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
11 //从数据库中获取权限并放且放到授权对象中
12 Set<String> permission = permissionService.findByLoginUser();
13 authorizationInfo.setStringPermissions(permission);
14 return authorizationInfo;
15 }
16 @Override//身份认证
17 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
18 //拿到令牌(UsernamePasswordToken)
19 UsernamePasswordToken taken = (UsernamePasswordToken) authenticationToken;
20 //拿到用户名,判断这个用户是否存在
21 String username = taken.getUsername();
22 //根据用户名从数据库中拿到用户对象
23 Employee employee = employeeService.findByUsername(username);
24 //如果没有拿到密码(没有通过用户名拿到相应的用户->用户不存在)
25 if(employee==null){
26 return null;
27 }
28 //拿到咱们的盐值对象(ByteSource)
29 ByteSource source = ByteSource.Util.bytes("itsource");
30 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, employee.getPassword(), source, "JpaRealm");
31 return authenticationInfo;
32 }
33 }
知识兔applictionContest-shiro.xml中的配置
<bean id="jpaRealm" class="com.logo.aisell.web.shiro.JpaRealm">
<!--Realm的名称-->
<property name="name" value="jpaRealm"/>
<property name="credentialsMatcher">
<!-- 配置哈希密码匹配器 -->
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!--加密方式:MD5-->
<property name="hashAlgorithmName" value="MD5"/>
<!--迭代次数-->
<property name="hashIterations" value="10" />
</bean>
</property>
</bean>
知识兔6:自定义过滤器用于过滤请求 修改过滤路径后需要重新启动服务器
public class ShiroFilterMapFactory {
@Autowired
private IPermissionService permissionService;
public Map<String,String> creatMap(){
LinkedHashMap<String, String> map = new LinkedHashMap<>();
//anon:需要放行的路径
map.put("/login","anon");
map.put("/easyui/**","anon");
map.put("/images/**","anon");
map.put("/js/**","anon");
map.put("/s/**","anon");
map.put("*.js","anon");
//permissions:权限拦截 动态的从数据库中获取
map.put("*.css","anon");
List<Permission> permissions = permissionService.findAll();
permissions.forEach(p -> {
map.put(p.getUrl(),"aiSellPerms["+p.getSn()+"]");
});
//authc:拦截
map.put("/**","authc");
return map;
}
}
知识兔applictionContext.shiro.xml中的配置
<property name="filters">
<map>
<entry key="aiSellPerms" value-ref="aiSellPermissionsAuthorizationFilter"></entry>
</map>
</property>
知识兔7:重写请求过滤器 shiro自带的请求过滤器会过滤掉AJax请求 重写过滤器 对AJax请求放行
1 public class AiSellPremissiAuthorizationFilter extends PermissionsAuthorizationFilter {
2
3 protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
4 Subject subject = this.getSubject(request, response);
5 //装换request response
6
7 if (subject.getPrincipal() == null) {
8 //没有登录的操作
9 this.saveRequestAndRedirectToLogin(request, response);
10 } else {
11 //登录成功后没有权限的操作
12 //1.转成http的请求与响应操作
13 HttpServletRequest httpRequest =(HttpServletRequest)request;
14 HttpServletResponse httpResponse=(HttpServletResponse)response;
15 ////2.根据请求确定是什么请求
16 String xRequestedWith = httpRequest.getHeader("X-Requested-With");
17 if(xRequestedWith != null &&"XMLHttpRequest".equals(xRequestedWith)){
18 //3.在这里就代表是ajax请求
19 //表示ajax请求 {"success":false,"message":"没有权限"}
20 httpResponse.setContentType("text/json; charset=UTF-8");
21 httpResponse.getWriter().print("{\"success\":false,\"msg\":\"没有权限\"}");
22 }else {
23 //普通请求的返回方式
24 String unauthorizedUrl = this.getUnauthorizedUrl();
25 if (StringUtils.hasText(unauthorizedUrl)) {
26 WebUtils.issueRedirect(request, response, unauthorizedUrl);
27 } else {
28 WebUtils.toHttp(response).sendError(401);
29 }
30 }
31
32 }
33
34 return false;
35 }
36 }
知识兔applictionContext.shiro.xml中的配置
<!--配置我们的自定义权限过滤器-->
<bean id="aiSellPermissionsAuthorizationFilter"
class="com.logo.aisell.web.shiro.AiSellPremissiAuthorizationFilter">
</bean>
知识兔