简单权限系统基于shiro-springmvc-spring-mybatis(学习笔记2)
2016-10-13 14:36
651 查看
学习笔记(1)链接:http://blog.csdn.net/qq_15370821/article/details/52798276
一个简单的权限管理系统,实现用户、权限、资源的增删改查,这三者之间相互的授权和取消授权,如:一个用户可以拥有多个权限并且一个权限可以拥有多个资源。
系统基于shiro、springmvc、spring、mybatis,使用MySQL数据库。
项目地址:https://git.oschina.net/beyondzl/spring-shiro
(前端视图由于时间原因没有全部完成,后端功能测试可行)
基础Controller类:
handler继承基本Controller类:
ehcache配置
ehcache-shiro.xml:
shiro权限认证类:
字符串处理工具类:
web.xml:
一个简单的权限管理系统,实现用户、权限、资源的增删改查,这三者之间相互的授权和取消授权,如:一个用户可以拥有多个权限并且一个权限可以拥有多个资源。
系统基于shiro、springmvc、spring、mybatis,使用MySQL数据库。
项目地址:https://git.oschina.net/beyondzl/spring-shiro
(前端视图由于时间原因没有全部完成,后端功能测试可行)
Web层
springmvc.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" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <mvc:annotation-driven > <mvc:message-converters register-defaults="false"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="utf-8"></constructor-arg> </bean> <ref bean="jacksonMessageConverter"></ref> </mvc:message-converters> </mvc:annotation-driven> <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> <property name="objectMapper" ref="jacksonObjectMapper"></property> </bean> <context:component-scan base-package="com.spring.shiro.main.java.controller"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> <!-- 有多个视图解析器时的优先级 --> <property name="order" value="10"></property> </bean> </beans>
基础Controller类:
public abstract class BaseController { @Autowired private UserService userService ; /** * 日期格式转换 * @param binder */ @InitBinder public void initBinder(ServletRequestDataBinder binder) { binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true)); /** * 防止XSS攻击 */ binder.registerCustomEditor(String.class, new StringEscapeEditor(true,false)); } /** * 获取当前登录用户 * @return */ public User getCurrentUser() { ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal(); User currentUser = userService.findUserById(user.id); return currentUser; } /* * 获取当前用户id */ public Long getUserUd() { return this.getCurrentUser().getId(); } /** * 获取当前用户名 * @return */ public String getStaffName() { return this.getCurrentUser().getName(); } /** * ajax失败 * @param msg 失败的消息 * @return */ public Object renderError(String msg) { Result result = new Result(); result.setMsg(msg); return result; } /** * ajax成功 * @return */ public Object renderSuccess() { Result result = new Result(); result.setSuccess(true); return result; } /** * ajax成功消息 * @param msg * @return */ public Object renderSuccess(String msg) { Result result = new Result(); result.setSuccess(true); result.setMsg(msg); return result; } /** * ajax成功时的对象 * @param obj * @return */ public Object renderSuccess(Object obj) { Result result = new Result(); result.setSuccess(true); result.setObj(obj); return result; } }
handler继承基本Controller类:
@Controller @RequestMapping("/user") public class UserController extends BaseController { @Autowired private UserService userService; /** * 用户管理页 * @return */ @RequestMapping(value="/manager",method=RequestMethod.GET) public String manager() { return "/admin/user"; } /** * 用户管理列表 * @param userVo * @param page * @param rows * @param sort * @return */ @RequestMapping(value="/dataGrid", method=RequestMethod.POST) @ResponseBody public Object dataGrid(UserVo userVo, Integer page, Integer rows, String sort) { PageInfo pageInfo = new PageInfo(page, rows); Map<String, Object> condition = new HashMap<String, Object>(); if(StringUtils.hasText(userVo.getName())) { condition.put("name", userVo.getName()); } if(userVo.getOrganizationId() != null) { condition.put("organizationId", userVo.getOrganizationId()); } if(userVo.getCreatedateStart() != null) { condition.put("startTime", userVo.getCreatedateStart()); } if(userVo.getCreatedateEnd() != null) { condition.put("endTime", userVo.getCreatedateEnd()); } pageInfo.setCondition(condition); userService.findUserGrid(pageInfo); return pageInfo; } /** * 添加用户页 * @return */ @RequestMapping(value="addPage", method=RequestMethod.GET) public String addPage() { return "/admin/userAdd"; } /** * 添加用户 * @param userVo * @return */ @RequestMapping(value="/add",method=RequestMethod.POST) @ResponseBody public Object add(UserVo userVo) { User user = userService.findUserByLoginName(userVo.getLoginName()); if(user != null) { return renderError("用户名已存在!"); } try { userVo.setPassword(DigestUtils.md5Hex(userVo.getPassword().getBytes("UTF-8"))); } catch (UnsupportedEncodingException e) { return renderSuccess("添加失败!"); } userService.addUser(userVo); return renderSuccess("添加成功!"); } /** * 编辑用户页 * @param id * @param model * @return */ @RequestMapping("/editPage") public String editPage(Long id,Model model) { UserVo userVo = userService.findUserVoById(id); List<Role> rolesList = userVo.getRolesList(); List<Long> idsList = new ArrayList<Long>(); for(Role role : rolesList) { idsList.add(role.getId()); } model.addAttribute("roleIds", rolesList); model.addAttribute("user", userVo); return "/admin/userEdit"; } @RequestMapping("/edit") @ResponseBody public Object edit(UserVo userVo) { User user = userService.findUserByLoginName(userVo.getLoginName()); if(user != null && user.getId() != userVo.getId()) { return renderError("用户名已存在!"); } try { userVo.setPassword(DigestUtils.md5Hex(userVo.getPassword().getBytes("UTF-8"))); } catch (UnsupportedEncodingException e) { return renderError("添加失败!"); } userService.addUser(userVo); return renderSuccess("添加成功!"); } /** * 修改密码页 * @return */ @RequestMapping(value="/editPwdPage", method=RequestMethod.GET) public String editPwdPage() { return "/admin/userEditPwd"; } @RequestMapping("/editUserPwd") @ResponseBody public Object editUserPwd(String oldPwd, String pwd) { try { if(!getCurrentUser().getPassword().equals(DigestUtils.md5Hex(oldPwd.getBytes("UTF-8")))) { return renderError("旧密码错误!"); } } catch (UnsupportedEncodingException e) { return renderError("修改失败!"); } userService.updateUserPwdById(getUserUd(), pwd); return renderSuccess("修改成功!"); } @RequestMapping("/delete") @ResponseBody public Object delete(Long id) { userService.deleteUserById(id); return renderSuccess("删除成功!"); } }
spirng整合shiro
spring-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.xsd"> <description>shiro安全配置</description> <!-- 安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" > <!-- 设置自定义realm --> <property name="realm" ref="shiroDbRealm"></property> <!-- 将缓存管理器交给安全管理器 --> <property name="cacheManager" ref="shiroEhcacheManager"></property> </bean> <!-- 自定义realm --> <bean id="shiroDbRealm" class="com.spring.shiro.main.common.shiro.ShiroDbRealm"></bean> <!-- shiro Filter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 安全管理器 --> <property name="securityManager" ref="securityManager"></property> <!-- 默认的登陆访问url --> <property name="loginUrl" value="/login"></property> <!-- 登陆成功后跳转的url --> <property name="successUrl" value="/index"></property> <!-- 没有权限跳转的url --> <property name="unauthorizedUrl" value="/unauth"></property> <property name="filterChainDefinitions"> <value> /commons/** = anon <!-- 不需要认证 --> /static/** = anon /login = anon /** = authc <!-- 需要认证 --> </value> </property> </bean> <!-- 用户授权信息cache 才用Ehcache --> <bean id="ShiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"></property> </bean> <!-- 在方法中注入securityManager进行代理控制 --> <bean class="org.springframework.beans.factory.config.MethodInvokingBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"></property> <property name="arguments" ref="securityManager"></property> </bean> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean> <!-- AOP方法级权限检查 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"></bean> <!-- 启用shiro授权注解拦截方式 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"></property> </bean> </beans>
ehcache配置
ehcache-shiro.xml:
<?xml version="1.0" encoding="UTF-8"?> <ehcache updateCheck="false" name="shiroCache"> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" overToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> </ehcache>
shiro权限认证类:
public class ShiroDbRealm extends AuthorizingRealm { private static Logger LOGGER = LogManager.getLogger(ShiroDbRealm.class); @Autowired private UserService userService; @Autowired private RoleService roleService; /** * 权限认证 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { ShiroUser shiroUser = (ShiroUser)principal.getPrimaryPrincipal(); List<Long> roleList = shiroUser.roleList; Set<String> urlSet = new HashSet<String>(); for(Long roleId : roleList) { List<Map<Long, String>> roleResourceList = roleService.findRoleResourceListByRoleId(roleId); if(roleResourceList != null) { for(Map<Long,String> map : roleResourceList) { if(StringUtils.hasText(map.get("url"))) { urlSet.add(map.get("url")); } } } } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermissions(urlSet); return info; } /** * shiro登陆认证 用户提交用户名密码,shiro封装令牌,realm通过用户名密码查询返回,shiro自动比较用户名密码是否匹配哦,进行登陆控制 */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authcToken) throws AuthenticationException { LOGGER.info("Shiro开始登陆认证"); UsernamePasswordToken token = (UsernamePasswordToken) authcToken; User user = userService.findUserByLoginName(token.getUsername()); if(user == null) { return null; } //账号未启用 if(user.getStatus() == 1) { return null; } List<Long> roleList = roleService.findRoleIdsByUserId(user.getId()); ShiroUser shiroUser = new ShiroUser(user.getId(), user.getLoginName(), user.getName(),roleList); //认证缓存器 return new SimpleAuthenticationInfo(shiroUser, user.getPassword().toCharArray(), getName()); } }
字符串处理工具类:
public class StringEscapeEditor extends PropertyEditorSupport{ private boolean escaoeHTML; //编码HTML private boolean escapeJavaScript; //编码javascript public StringEscapeEditor(){} public StringEscapeEditor(boolean escapeHTML, boolean escapeJavaScipt){ this.escaoeHTML = escapeHTML; this.escapeJavaScript = escapeJavaScipt; } @Override public String getAsText() { Object value = getValue(); return value != null ? value.toString() : ""; } @Override public void setAsText(String text) { if(text == null) { setValue(null); } else { String value = text; if(escaoeHTML) { value = HtmlUtils.htmlEscape(value); } if(escapeJavaScript) { value = JavaScriptUtils.javaScriptEscape(value); } setValue(value); } } }
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>spring-shiro</display-name> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- springmvc控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet.class</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <!-- 是否支持异步 --> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>DruidWebStatFilter</filter-name> <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class> <init-param> <param-name>exclusions</param-name> <param-value>/static/*,*.js,*.gif,*.png,*.css,*.ico,/druid/*</param-value> </init-param> <init-param> <param-name>sessionStatEnable</param-name> <param-value>false</param-value> </init-param> </filter> <filter-mapping> <filter-name>DruidWebStatFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- shiro过滤 --> <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> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <!-- 错误页面 --> <error-page> <error-code>404</error-code> <location>/WEB-INF/views/error/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/views/error/500.jsp</location> </error-page> </web-app>
相关文章推荐
- 简单权限系统基于shiro-springmvc-spring-mybatis(学习笔记 1)
- springmvc-spring-mybatis-shiro-easyui权限系统
- 【基于shiro的分布式权限管理系统】一个用Java、spring、mybatis和shiro开发的分布式权限管理系统
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例
- 基于Maven + SSM (Spring、SpringMVC、Mybatis)构建一个简单的
- java maven、springmvc、mybatis 搭建简单Web项目学习笔记
- SSM简单整合(Mybatis,Spring,SpringMVC,基于注解和xml文件配置)
- 基于Spring、SpringMVC、MyBatis、Druid、Shrio构建web系统
- 基于Spring-SpringMVC-Mybatis的简单样例
- 基于Spring+SpringMVC+Mybatis分布式敏捷开发系统架构---权限管理系统
- 基于现如今流行的SSM(spring springMVC mybatis mysql)框架的hrm人事管理系统后台实例
- Spring Boot 学习二、基于SpringBoot + Mybatis实现SpringMVC Web项目
- SpringMVC+Spring Data JPA+Shiro+EasyUI简单权限管理系统
- 简单两步快速实现shiro的配置和使用,包含登录验证、角色验证、权限验证以及shiro登录注销流程(基于spring的方式,使用maven构建)
- spring+springmvc+mybatis shiro权限管理系统demo mysql数据库
- SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例