1.在pom添加集成导入
<!-- shiro的支持包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.4.0</version> <type>pom</type> </dependency> <!-- shiro与Spring的集成包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency>
2.在WEB-INF/web.xml中添加一个过滤器
<!-- Shiro Filter is defined in the spring application context: --> <!--配置一个DelegatingFilterProxy这是一个下放权限,把请求让给 <filter-name>shiroFilter</filter-name>通过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>
2.写一个配置文件
自定义一个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"> <!-- DefaultSecurityManager securityManager = new DefaultSecurityManager();--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--引入到securityManager的realm--> <property name="realm" ref="myRealm"/> </bean> <!--配置我自己的realm--> <bean id="myRealm" class="cn.jiedada.aisell.web.controller.shiro.MyRealm"> <!--name无关紧要--> <property name="name" value="myRealm"/> <!----> <property name="credentialsMatcher"> <!-- 设置密码解析器 HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("MD5"); hashedCredentialsMatcher.setHashIterations(10); --> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"/> <property name="hashIterations" value="10"/> </bean> </property> </bean> <!--下放请求到当前页面--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--当我们没登陆的是否跳到当前页面--> <property name="loginUrl" value="/s/login.jsp"/> <!--登陆成功调到该页面--> <property name="successUrl" value="/s/index.jsp"/> <!--有权限的,如果没有则跳转到该页面--> <property name="unauthorizedUrl" value="/s/unauthorized.jsp"/> <!--/s/login = anon放行 /s/permission.jsp = perms[user:index]需要user:index权限才能访问 /** = authc --> <!-- <property name="filterChainDefinitions"> <value> /s/login = anon /login = anon /s/permission.jsp = perms[user:index] /** = authc </value> </property>--> <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property> </bean> <bean id="filterChainDefinitionMap" factory-bean="shiroFilterMapFactory" factory-method="createMap" /> <!--配置返回shiro权限拦截的bean--> <bean id="shiroFilterMapFactory" class="cn.jiedada.aisell.web.controller.shiro.ShiroFilterMapFactory"/> </beans>
3.要把该配置写入applicationContext.xml中
<!--把applicationContext-shiro.xml放在spring中运行--> <import resource="classpath:applicationContext-shiro.xml"/>
就完成了最基础的配置
这里是MyRealm
package cn.jiedada.aisell.web.controller.shiro; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import java.util.HashSet; import java.util.Set; public class MyRealm extends AuthorizingRealm { /*授权 * */ protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); //设置冲数据库中传来的角色 simpleAuthorizationInfo.setRoles(this.getRoles()); //设置冲数据库中传来的权限 simpleAuthorizationInfo.setStringPermissions(getPerms()); return simpleAuthorizationInfo; } private Set getRoles(){ Set set = new HashSet(); set.add("admin"); return set; } private Set getPerms(){ Set set = new HashSet(); set.add("employee:index"); return set; } /*身份验证 返回值null为用户名错误 * */ protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //获得token序列 UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken; //获得用户名 String username = token.getUsername(); //去数据库查询密码 String pwd = getUsers(username); if(pwd!=null){ //验证密码,传入三个参数 //设置盐 ByteSource byteSource = ByteSource.Util.bytes("jiedada"); SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username,pwd,byteSource,"myshiro"); return simpleAuthenticationInfo; } return null; } private String getUsers(String username){ if("adimn".equals(username)){ return "2a7e4163f7f9f316d03c3f384eeb301b"; } return null; } }
这个比较好一点
package cn.jiedada.crm.web.shiro; import cn.jiedada.crm.domain.Employee; import cn.jiedada.crm.domain.Permission; import cn.jiedada.crm.service.IEmployeeService; import cn.jiedada.crm.service.IPermissionService; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import java.util.HashSet; import java.util.Set; public class MyRealm extends AuthorizingRealm { @Autowired private IEmployeeService employeeService; @Autowired private IPermissionService permissionService; /*授权 * */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); //设置冲数据库中传来的角色 //simpleAuthorizationInfo.setRoles(this.getRoles()); //设置冲数据库中传来的权限 Set<String> pers = permissionService.findLogSn(); simpleAuthorizationInfo.setStringPermissions(pers); return simpleAuthorizationInfo; } /*省份验证*/ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //获得token UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; //获得用户名 String username = token.getUsername(); //在数据库中查找获得数据 Employee employee = employeeService.findEmployeeByUsername(username); //判断是否为空 if(employee==null){ throw new UnknownAccountException(username); } //设置principal Object principal = employee; //获得数据库的密码 Object hashedCredentials = employee.getPassword(); ByteSource credentialsSalt = ByteSource.Util.bytes(MD5Util.SALT); String realmName = getName(); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal,hashedCredentials,credentialsSalt,realmName); return info; } }
这里是ShiroFilterMapFactory
package cn.jiedada.aisell.web.controller.shiro; import java.util.LinkedHashMap; import java.util.Map; /** * 用于返回下面的这些值(这里的值是有顺序的:LinkedHashMap) * <value> /login = anon /s/permission.jsp = perms[user:index] /** = authc </value> */ public class ShiroFilterMapFactory { public Map<String,String> createMap(){ Map<String,String> map = new LinkedHashMap<>(); //anon:需要放行的路径 map.put("/login","anon"); //perms:权限拦截 map.put("/s/permission.jsp","perms[employee:index]"); //authc:拦截 map.put("/**","authc"); return map; } }
因为会发送Ajax请求所以我们需要判断是否为ajax判断
AisellPermissionsAuthorizationFilter
package cn.jiedada.crm.web.shiro; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.StringUtils; import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter; import org.apache.shiro.web.util.WebUtils; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 写一个自己的Shiro来判断出我们需要的东西处理Ajax权限 */ public class AisellPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException { Subject subject = this.getSubject(request, response); //判断用户是否登陆 if (subject.getPrincipal() == null) { this.saveRequestAndRedirectToLogin(request, response); } else { //只用通过HttpServletRequest才能获得请求头中的数据才能判断 HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse=(HttpServletResponse)response; //查看是否是AjAX请求 String xRequested = httpRequest.getHeader("X-Requested-With"); if(xRequested!=null&&"XMLHttpRequest".equals(xRequested)){ //传入前需要在请求头中传入响应,让他知道我们返回的数据是AJAX请求 httpResponse.setContentType("text/json; charset=UTF-8"); //带回AJAX请求,把数据作为流传回去这里需要传出标准的json数据格式 httpResponse.getWriter().print( "{\"success\":false,\"msg\":\"没有权限\"}"); }else { String unauthorizedUrl = this.getUnauthorizedUrl(); if (StringUtils.hasText(unauthorizedUrl)) { WebUtils.issueRedirect(request, response, unauthorizedUrl); } else { WebUtils.toHttp(response).sendError(401); } } } return false; } }