SpringMVC+maven
项目需要使用shiro,所以自学了几天,仅提供给新手,请根据文档查看…该项目仅是测试项目,并不完善,只实现了需要使用的基本功能,并且只提供了使用shiro模块的代码。楼主新人第一次写,如有问题希望能提出来,由衷的感谢。
首先是pom.xml:
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.0</version> </dependency>
以下是web.xml配置:
<filter> <!-- filter-name需要和shiro的过滤器id一致 --> <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>
以下是shiro的配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- shior配置 begin --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!-- <property name="cacheManager" ref="cacheManager" /> --> <!-- 自定义的Realm --> <property name="realm" ref="myRealm" /> </bean> <!-- 缓存 --> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> </bean> <bean id="myRealm" class="com.renai.shop.service.admin.AuthenticationRealm"> <!-- 加密 --> <!-- <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="SHA-256"/> <property name="storedCredentialsHexEncoded" value="false"/> </bean> </property> --> </bean> <!-- SecurityManager是shiro的核心,协调shiro的各个组件 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> <!-- shiro过滤器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="/login/gotoLogin.html" /> <property name="unauthorizedUrl" value="/unauthorized.jsp" /> <property name="filterChainDefinitions"> <value> /login/gotoLogin.html = anon /login/login.html = anon /login/** = authc /sys/** = authc <!-- /sys/add/** = authc, roles[manager] /sys/update/** = authc, roles[admin] /sys/delete/** = authc, perms[delete] --> </value> </property> </bean> </beans>
以下是自定义的Realm类:
package com.renai.shop.service.admin; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; 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.springframework.beans.factory.annotation.Autowired; import com.renai.shop.dao.mapper.SysDictionaryMapper; import com.renai.shop.filter.admin.AdmUserInfoFilter; import com.renai.shop.model.admin.AdmPermission; import com.renai.shop.model.admin.AdmRole; import com.renai.shop.model.admin.AdmUserInfo; /** * @作者 zjm * @类说明: * @创建日期 2015年03月19日 * @版本 V 1.0 */ public class AuthenticationRealm extends AuthorizingRealm { @Autowired private SysDictionaryMapper sysDictionaryMapper; /** * 给权限 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) throws AuthenticationException{ System.out.println("---------------doGetAuthorizationInfo---------------"); //获取用户名 String userName = (String) getAvailablePrincipal(principals); SimpleAuthorizationInfo info = null; if (userName != null) { //自定义实体类查询时的过滤器 AdmUserInfoFilter userInfoFilter = new AdmUserInfoFilter(); userInfoFilter.setUserName(userName); //按照yonghumi List<AdmUserInfo> userInfos = sysDictionaryMapper .selectUserInfoByFilter(userInfoFilter); if (userInfos.size() > 0) { List<AdmRole> roles = userInfos.get(0).getRoles(); Set<String> roleNames = new HashSet<String>(); Set<String> permissions = new HashSet<String>(); for (AdmRole role : roles) { roleNames.add(role.getName()); for (AdmPermission permission : role.getPermissions()) { permissions.add(permission.getOperation()); } } info = new SimpleAuthorizationInfo(roleNames); info.setStringPermissions(permissions); } } else { System.out.println("---------------用户名不能为空!---------------"); } return info; } /** * 登陆验证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { System.out.println("---------------doGetAuthenticationInfo---------------"); UsernamePasswordToken upToken = (UsernamePasswordToken)token; SimpleAuthenticationInfo info = null; String userName = upToken.getUsername(); String passWord = String.valueOf(upToken.getPassword()); AdmUserInfo userInfo = sysDictionaryMapper.login(userName, passWord); if (userInfo == null) { //抛出的异常在LoginController中处理 throw new UnknownAccountException("用户名或密码错误"); } try { info = new SimpleAuthenticationInfo(userName, passWord, getName()); } catch (Exception e) { throw new AuthenticationException("验证失败", e); } return info; } }
登录Controller:
package com.renai.shop.admin.controller; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.annotations.Param; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.renai.shop.filter.admin.AdmMenuFilter; import com.renai.shop.filter.admin.AdmUserInfoFilter; import com.renai.shop.model.admin.AdmMenu; import com.renai.shop.model.admin.AdmUserInfo; import com.renai.shop.service.admin.api.ISysDictionaryService; /** * @作者 zjm * @类说明: * @创建日期 2015年03月19日 * @版本 V 1.0 */ @RequestMapping(value = "/login") @Controller public class LoginController { @Autowired private ISysDictionaryService sysDictionaryService; @RequestMapping(value = "/gotoLogin.html") public String goToLogin(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) { return "login"; } @RequestMapping(value = "/login.html") @ResponseBody public String login(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap, @Param(value = "username") String username, @Param(value = "password") String password) { UsernamePasswordToken token = new UsernamePasswordToken(username, password); // 记住令牌 token.setRememberMe(true); Subject subject = SecurityUtils.getSubject(); try { subject.login(token); } catch (UnknownAccountException ex) { System.out.println("用户名没有找到" + ex.toString()); return "error"; } catch (IncorrectCredentialsException ex) { System.out.println("用户名密码不匹配" + ex.toString()); return "error"; } catch (AuthenticationException e) { System.out.println("其他的登录错误" + e.toString()); return "error"; } catch (Exception e) { System.out.println("登陆失败" + e.toString()); return "error"; } return "success"; } @RequestMapping(value = "/goToIndex.html") public String goToIndex(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap) { Subject subject = SecurityUtils.getSubject(); String userName = subject.getPrincipal().toString(); if (StringUtils.isNotBlank(userName)) { AdmUserInfoFilter userInfoFilter = new AdmUserInfoFilter(); userInfoFilter.setUserName(userName); List<AdmUserInfo> userInfos = sysDictionaryService .selectUserInfoByFilter(userInfoFilter); if (userInfos.size() > 0) { AdmUserInfo userInfo = userInfos.get(0); AdmMenuFilter filter = new AdmMenuFilter(); filter.setMenuType(1); // 查询权限 if (userInfo.getRoles().size() > 0) { List<AdmMenu> menuList = sysDictionaryService .selectMenuByRolesId( userInfo.getAdmUserRoleInfos(), filter); request.getSession().setAttribute("menuList", menuList); } } } return "index"; } }
系统Controller:
package com.renai.shop.admin.controller; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.annotations.Param; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.renai.shop.admin.service.AdmRoleVO; import com.renai.shop.admin.service.AdmUserInfoVO; import com.renai.shop.filter.admin.AdmMenuFilter; import com.renai.shop.filter.admin.AdmPermissionFilter; import com.renai.shop.filter.admin.AdmRoleFilter; import com.renai.shop.filter.admin.AdmUserInfoFilter; import com.renai.shop.model.admin.AdmMenu; import com.renai.shop.model.admin.AdmPermission; import com.renai.shop.model.admin.AdmRole; import com.renai.shop.model.admin.AdmUserInfo; import com.renai.shop.service.admin.api.ISysDictionaryService; /** * @作者 zjm * @类说明: * @创建日期 2015年03月19日 * @版本 V 1.0 */ @RequestMapping(value = "/sys") @Controller public class SysController { @Autowired private ISysDictionaryService sysDictionaryService; @RequestMapping(value = "/getMenuByParent.html") public String getMenuByParent(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap, @Param(value = "parentId") int parentId) { Subject subject = SecurityUtils.getSubject(); String userName = subject.getPrincipal().toString(); if (StringUtils.isNotBlank(userName)) { AdmUserInfoFilter userInfoFilter = new AdmUserInfoFilter(); userInfoFilter.setUserName(userName); List<AdmUserInfo> userInfos = sysDictionaryService .selectUserInfoByFilter(userInfoFilter); if(userInfos.size() > 0){ AdmUserInfo userInfo = userInfos.get(0); AdmMenuFilter filter = new AdmMenuFilter(); filter.setMenuType(2); filter.setParentId(parentId); // 查询权限 if (userInfo.getRoles().size() > 0) { List<AdmMenu> thirdMenuList = sysDictionaryService .selectMenuByRolesId(userInfo.getAdmUserRoleInfos(), filter); request.getSession().setAttribute("thirdMenuList", thirdMenuList); } } } return "ajax/ajaxGetMenu"; } }
以下是页面:
使用shiro的标签需要引用:
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>1
以下是按照登录时保存的权限显示按钮
<div class="tools"> <ul class="toolbar"> <shiro:hasPermission name="add"> <li class="click" onclick="add()"> <span><img src="${ctx}/skin/images/t01.png"></span>添加 </li> </shiro:hasPermission> <shiro:hasPermission name="update"> <li class="click" onclick="update()"> <span><img src="${ctx}/skin/images/t02.png"></span>修改 </li> </shiro:hasPermission> <shiro:hasPermission name="delete"> <li onclick="deletes()"> <span><img src="${ctx}/skin/images/t03.png"></span>删除 </li> </shiro:hasPermission> </ul> </div>
以下是项目数据
表
菜单表
角色表
权限表
以下是项目页面部分截图
第一个是“boos”角色登陆
第二个是“manager”角色登陆
第三个是“admin”角色登陆