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>