近期由于使用shiro作为安全框架作为项目中要使用的权限管理,在此分享一下shiro于spring和springmvc集成的demo
1.首先添加web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" metadata-complete="true"> <display-name>shiro测试</display-name> <!-- shiroFilter --> <filter> <filter-name>shiroFilter</filter-name> <!-- 代理类,自动到spring配置文件中找shiro配置文件 --> <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> <!-- 加载spring配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:beans.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- springmvc配置文件加载 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</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> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 使用spring解决乱码问题 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>
2.SpringMVC配置文件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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <!-- <bean id="myController" name="/control.action" class="com.cai.controller.MyController"></bean> --> <!-- 支持注解驱动 --> <mvc:annotation-driven/> <!-- shiro中注解起作用必须配置在springmvc配置文件中,配置在其他地方无效 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true" /> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <!-- 配置异常跳转页面,此处异常页面是使用shiro注解时没有权限访问的跳转页面,不配置则会报500错误 --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException"> <!-- 没有权限时跳转的页面 --> /unauthorized </prop> <prop key="org.apache.shiro.authz.UnauthenticatedException"> <!-- 认证错误时跳转的页面 --> /unauthenticated </prop> </props> </property> </bean> <!-- 组件扫描的包 --> <context:component-scan base-package="com.cai.controller"/> <!-- 静态资源目录 --> <mvc:resources mapping="/js/**" location="/js/" /> <mvc:resources mapping="/images/**" location="/images/" /> <mvc:resources mapping="/css/**" location="/css/" /> <mvc:resources mapping="/common/**" location="/common/" /> <!-- 配置视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 通过setter方法注入前缀 --> <property name="prefix" value="/WEB-INF/pages/"/> <!-- 通过setter方法注入后缀 --> <property name="suffix" value=".jsp"></property> </bean> </beans>
3.Spring配置文件beans.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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <!-- 组件扫描 --> <context:component-scan base-package="com.cai.*"/> <!--数据库配置:配置jdbc.properties --> <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 3、配置dataSource数据源c3p0 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <!-- <property name="maxPoolSize" value="${c3p0.pool.maxPoolSize}"/> <property name="minPoolSize" value="${c3p0.pool.minPoolSize}"/> <property name="initialPoolSize" value="${c3p0.pool.initialPoolSize}"/> <property name="acquireIncrement" value="${c3p0.pool.acquireIncrement}"/> --> </bean> <!-- 数据源使用Spring自带的jdbctemplate --> <bean id="jdbcTemplate" name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="userDao" name="userDao" class="com.cai.dao.UserDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <bean id="baseDao" name="baseDao" class="com.cai.dao.BaseDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- <bean id="baseDao" name="baseDao" class="com.cai.dao.BaseDao"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> --> <!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 导入shiro配置文件 --> <import resource="shiro.xml"/> </beans>
4.jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/shiro?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=123456
5.缓存ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> </ehcache>
6.java代码
MD5加密
public class MD5Utils { /** * 使用md5的算法进行加密 * 此处使用的是shiro自带的md5加密方法 */ public static String md5(String password) { Md5Hash md5 = new Md5Hash(password); return md5.toString(); } }
实体类javabean
public class User { private int id; private String username;//用户名 private String password;//用户密码 private String realname;//真实名字 private String email;//emai地址 private String phone;//电话号码 private List<Role> roles = new ArrayList<Role>(); /** * @return the roles */ public List<Role> getRoles() { return roles; } /** * @param roles the roles to set */ public void setRoles(List<Role> roles) { this.roles = roles; } ....都是get、set方法 }
public class Role { private int id; private String rolename;//角色名 private String roletype;//角色类型 List<Permission> perms = new ArrayList<Permission>(); /** * @return the perms */ public List<Permission> getPerms() { return perms; } /** * @param perms the perms to set */ public void setPerms(List<Permission> perms) { this.perms = perms; } //...get set方法 }
public class Permission { private int id; private String permname;//权限名称 private String operation;//权限操作 private String description;//权限描述 /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } //...get set方法 }
Dao层
@Repository public class BaseDao extends JdbcDaoSupport { /** * 条件查询 * @param sql * @param id * @return */ public Map<String, Object> querySingle(String sql,Object... args) { return this.getJdbcTemplate().queryForMap(sql, args); } /** * 根据sql查询 * @param sql * @return */ public Map<String, Object> queryAll(String sql) { return this.getJdbcTemplate().queryForMap(sql); } /** * 查询集合 * @param sql * @return */ public List<Map<String, Object>> queryList(String sql) { return this.getJdbcTemplate().queryForList(sql); } /** * 条件查询集合 * @param sql * @param args * @return */ public List<Map<String, Object>> queryList(String sql, Object... args) { return this.getJdbcTemplate().queryForList(sql, args); } /** * 更新记录条数 * @param sql * @return */ public int update(String sql) { return this.getJdbcTemplate().update(sql); } /** * 按条件更新 * @param sql * @param args * @return */ public int update(String sql, Object... args) { return this.getJdbcTemplate().update(sql, args); } /** * 添加记录 * @param sql */ public void add(String sql) { this.getJdbcTemplate().execute(sql); } /** * 删除记录 * @param sql */ public void delete(String sql) { this.getJdbcTemplate().execute(sql); } }
@Repository public class UserDao extends JdbcDaoSupport { /** * 登录查询 * @param sql * @param username * @param password * @return */ public Map<String, Object> loginQuery(String sql, String username, String password) { return this.getJdbcTemplate().queryForMap(sql, username, password); } /** * 登录查询 * @param sql * @param username * @param password * @return */ public Map<String, Object> loginQuery(String sql, String username) { return this.getJdbcTemplate().queryForMap(sql, username); } }
Service 层
@Service public class UserService { @Autowired UserDao userDao; @Autowired BaseDao baseDao; public Map<String, Object> queryLogin(String username, String password) { String sql = "select username, password from user where username=? and password=?"; return userDao.loginQuery(sql, username, password); } public User queryLogin(String username) { String sql = "select * from user where username=?"; Map<String, Object> query = userDao.loginQuery(sql,username); User user = new User(); if(query != null && query.size() > 0) { if(query.get("id") != null) { user.setId(Integer.parseInt(query.get("id").toString())); } if(query.get("username") != null) { user.setUsername(query.get("username").toString()); } if(query.get("password") != null) { user.setPassword(query.get("password").toString()); } if(query.get("realname") != null) { user.setRealname(query.get("realname").toString()); } if(query.get("email") != null) { user.setEmail(query.get("email").toString()); } if(query.get("phone") != null) { user.setPhone(query.get("phone").toString()); } } return user; } }
@Service public class ShiroService { @Autowired BaseDao baseDao; /** * 根据角色id获取对应的权限id * @param roleid * @return */ public List<Map<String, Object>> getPermissions(int roleid) { String sql = "select * from role_permission where role_id=?"; return baseDao.queryList(sql, roleid); } /** * 通过用户id获取角色 * @param userid * @return */ public List<Map<String, Object>> getRoles(int userid){ String sql = "select * from role where id in (select role_id from user_role where user_id=?)"; return baseDao.queryList(sql, userid); } /** * 添加权限id * @param permid */ /*public void addPerm(int permid) { String sql = "insert into role_permission"; }*/ /** * 查询所有的权限 * @param role * @return */ public List<Map<String, Object>> getPermissions(Role role) { String sql = "select * from permission where id in (SELECT permission_id from role_permission WHERE role_id=?)"; return baseDao.queryList(sql, role.getId()); } /** * 查询所有的角色 * @param user * @return */ public List<Map<String, Object>> getRoles(User user) { String sql = "select * from role where id in (select role_id from user_role where user_id=?)"; return baseDao.queryList(sql, user.getId()); } }
Shiro核心
@Service public class MyRealm extends AuthorizingRealm{ @Autowired ShiroService shiroService; @Autowired UserService userService; /* (non-Javadoc) * @see org.apache.shiro.realm.AuthorizingRealm#doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection) * 授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //获取当前登录用户名 //String account = (String) principals.fromRealm(getName()).iterator().next(); // String account = (String)getAvailablePrincipal(principals); Subject subject = SecurityUtils.getSubject(); String account = (String) subject.getPrincipal(); User user = userService.queryLogin(account); List<Map<String,Object>> roleList = shiroService.getRoles(user); for (Map<String, Object> roles : roleList) { authorizationInfo.addRole(roles.get("roletype").toString()); Role role = new Role(); role.setId(Integer.parseInt((roles.get("id").toString()))); List<Map<String, Object>> permissionsList = shiroService.getPermissions(role); for (Map<String, Object> perms : permissionsList) { authorizationInfo.addStringPermission(perms.get("operation").toString()); } } return authorizationInfo; } /* (non-Javadoc) * @see org.apache.shiro.realm.AuthenticatingRealm#doGetAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken) * 认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { //根据用户名查询数据库 UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;//封装认证对象 User user = userService.queryLogin(usernamePasswordToken.getUsername()); if(user == null) { //用户不存在 return null; } //返回密码 AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());//getName获取当前的realm //比较密码 return authenticationInfo; } }
Controller
@Controller public class UserController { @Autowired UserService userService; @RequestMapping(value="/login") public String login (HttpServletRequest request) { //非shiro登录 /*String username = request.getParameter("username"); String password = request.getParameter("password"); Map<String, Object> queryLogin = userService.queryLogin(username, MD5Utils.md5(password)); if(queryLogin != null) { return "success"; } else { return "fail"; }*/ return "login"; } @RequestMapping(value="/checklogin") @ResponseBody public String checkLogin(HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, MD5Utils.md5(password)); token.setRememberMe(true); try { subject.login(token); request.getSession().setAttribute("account", username); } catch (AuthenticationException e) { //e.printStackTrace(); return "/login"; } return "/first"; } @RequestMapping(value="/manage/first") public String main(HttpServletRequest request) { //String return "/manage/first"; } @RequestMapping(value="/operation/add") public String add(HttpServletRequest request) { return "/operation/add"; } //@RequiresRoles("administrator") @RequestMapping(value="/operation/delete") public String delete(HttpServletRequest request) { Subject subject = SecurityUtils.getSubject(); if(subject.hasRole("administrator")) { return "/operation/delete"; } else { return "/manage/unauthorized"; } } @RequestMapping(value="/operation/update") @RequiresRoles("header") public String update(HttpServletRequest request) { return "/operation/update"; } @RequestMapping(value="/operation/query") public String query(HttpServletRequest request) { return "/operation/query"; } @RequestMapping(value="/search/search") public String search(HttpServletRequest request) { return "/search/search"; } @RequestMapping(value="/manage/unauthorized") public String error(HttpServletRequest request) { return "/manage/unauthorized"; } @RequestMapping(value="/logout", method=RequestMethod.GET) public String logout() { Subject subject = SecurityUtils.getSubject(); if(subject.isAuthenticated()) { subject.logout(); //return "login"; } return "redirect:login"; } }
jsp页面在下面的文件中,下载后创建数据库执行sql,直接导入项目就行 了
相关推荐
项目描述 在上家公司自己集成的一套系统,用了两个多月的时间完成的:Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级开发系统 Springboot作为容器,使用mybatis作为持久层框架 使用官方推荐的thymeleaf做为...
在上家公司自己集成的一套系统,用了两个多月的时间完成的:Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级开发系统 Springboot作为容器,使用mybatis作为持久层框架 使用官方推荐的thymeleaf做为模板引擎...
这个集成方案利用Shiro的强大安全功能,SpringMVC的Web处理能力,Redis的高效缓存特性,以及MySQL的稳定存储,共同构建了一个安全、高效的单点登录系统。开发者可以根据具体需求调整这些组件的配置,以适应不同的...
项目描述 在上家公司自己集成的一套系统,用了两个多月的时间完成的:Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级开发系统 Springboot作为容器,使用mybatis作为持久层框架 使用官方推荐的thymeleaf做为...
在Shiro中,你需要理解Subject、Realms、Caching等核心概念,以及如何配置Shiro与Spring进行集成,实现权限控制和登录逻辑。 SpringMVC是Spring框架的一部分,专为Web应用设计。它提供了模型-视图-控制器(MVC)...
标题中的"Shiro + Hibernate5 + Spring5 + SpringMVC5 的jar"指的是一个整合了四个关键Java技术的库文件,这些技术分别是Apache Shiro、Hibernate5、Spring5和SpringMVC5。这个压缩包可能包含了这四个框架的最新版本...
4. **Web集成**:Shiro可以轻松地与SpringMVC集成,通过Filter配置实现URL级别的访问控制,为Web应用提供安全入口。 **SpringMVC与Shiro的整合** 1. **配置Shiro Filter**:在SpringMVC的web.xml中配置Shiro的...
本示例项目"springmvc+shiro+spring+hibernate+redis缓存管理示例"提供了一个全面的框架整合实例,它将几个关键的技术组件融合在一起,旨在帮助开发者实现更优的性能和安全性。以下是关于这些技术组件及其在项目中的...
5. **集成SpringMVC**:在SpringMVC的配置文件中,定义Shiro Filter,并将其注册到DispatcherServlet的过滤器链中。这通常通过`DelegatingFilterProxy`实现,它会代理到Spring容器中的Shiro Filter Bean。 6. **...
Shiro能够与SpringMVC(Spring 框架的一部分,用于构建MVC架构的Web应用)紧密集成,共同为Web应用提供全面的安全解决方案。 1. **Shiro核心概念**: - **认证**:验证用户的身份。在Shiro中,可以通过Subject对象...
【标题】"Shiro+SpringMVC+MyBatis+Maven"的集成与实践 在Web开发领域,Shiro、SpringMVC、MyBatis和Maven这四个组件是常见的技术栈,它们各司其职,共同构建了一个强大且灵活的后端系统。这个实例结合了这些工具,...
SpringMVC 是Spring框架的一个模块,用于构建高效的、组件化的Web应用程序。它遵循模型-视图-控制器(MVC)架构模式,解耦了业务逻辑、数据和用户界面。 - **DispatcherServlet**:作为SpringMVC的入口,负责接收...
在这个场景中,我们关注的是"shiro+springMVC+Mybatis"的整合应用,这是一种常见的技术栈,用于搭建基于Java的Web应用。这三个框架的结合,旨在提供用户认证、授权、会话管理和数据库操作等功能。 首先,让我们深入...
总之,这个"spring+springMVC+shiro 完美例子"是一个很好的学习资源,帮助开发者深入理解如何在Java Web应用中集成和使用这些强大的框架,实现安全、高效的权限管理。通过分析和实践这个例子,开发者不仅可以提升...
"shiro+SpringMVC+Spring+mybatis+maven+mybatis 自动刷新+Quartz scheduler 定时器"是一个常见的技术栈组合,每个组件都有其特定的功能和作用。 1. **Shiro**:Apache Shiro 是一个强大且易用的Java安全框架,提供...
本项目整合了多个流行的技术栈,包括Shiro、SpringMVC、Spring、MyBatis和Maven,这些组件共同构成了一个强大的开发基础。以下是对这些技术及其整合应用的详细说明: **Shiro**: Apache Shiro是一个轻量级的安全...
这个"springMVC+spring+mybatis(shiro+redis)框架样本"是一个综合性的项目实例,它整合了这五个关键组件,为开发者提供了一个全面的权限管理和数据访问解决方案。 1. **Spring框架**:Spring是Java企业级应用的...
Spring MVC 中,Shiro 可以通过 Spring 的依赖注入(DI)和面向切面编程(AOP)特性进行集成。首先,需要在 Spring 配置文件中声明 Shiro 的 Filter,并配置对应的 FilterChainDefinitionSource,以定义哪些 URL ...