java:shiroProject
1.backend_system Maven Webapp:
LoginController.java:
package com.shiro.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class LoginController { /** * @description 跳转到登录页面 * @return */ @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { return "login"; } /** * @description * 当form提交后,首先由shiro进行拦截,如果中途报错,shiro只是把错误信息打印控制台上,并不会真正意义上的报错 * shiro会直接全部放行,一切不再拦截,chain.doFilter()放行 * 路径直接会找controller * 找到controller后,发现该controller并没有post请求方式,报错吧! * 说白了,POST请求方式的login方法,是用来专门处理shiro抛出的异常的 * 在登录功能中,只要直接找到了controller,就一定登录失败! * 在shiro拦截的过程中,如果登录成功,shiro会默认返回项目的根目录"/" * @return */ @RequestMapping(value="/login", method=RequestMethod.POST) public String logins(Model model) { return "login"; } /** * @description 跳转到无权限页面 * @return */ @RequestMapping("/noauth") public String turnNoauth() { return "noauth"; } /** * @description 当登录成功后,跳转到页面 * 所有登录成功后,都从根目录下开始定向 * @return */ @RequestMapping("/") public String turnIndexPage() { // 默认用的是请求转发 return "list"; } }
ManagerController.java:
package com.shiro.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/manager") public class ManagerController { @RequestMapping(value = "book", method = RequestMethod.GET) public String turnBookPage() { // 请求转发 return "manager/books"; } }
AdminMapper.java:
package com.shiro.demo.mapper; import java.util.List; import com.shiro.demo.model.Admin; public interface AdminMapper { /** * @description 通过用户名查询用户信息 * @param username * @return */ public Admin selectAdminByUsername(String username); /** * @description 通过用户名查询该用户拥有的角色名称 * @param username * @return */ public List<String> selectRolesByUsername(String username); /** * @description 根据用户名查询出该用户下的所有权限 * @param username * @return */ public List<String> selectPermissionsByUsername(String username); }
PermissionMapper.java:
package com.shiro.demo.mapper; public interface PermissionMapper { }
RoleMapper.java:
package com.shiro.demo.mapper; public interface RoleMapper { }
Admin.java:
package com.shiro.demo.model; public class Admin { private Long id; private String username; private String password; private String salt; private Integer locked; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username == null ? null : username.trim(); } public String getPassword() { return password; } public void setPassword(String password) { this.password = password == null ? null : password.trim(); } public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt == null ? null : salt.trim(); } public Integer getLocked() { return locked; } public void setLocked(Integer locked) { this.locked = locked; } }
Permission.java:
package com.shiro.demo.model; public class Permission { private Long id; private String permissionName; private String permissionResource; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getPermissionName() { return permissionName; } public void setPermissionName(String permissionName) { this.permissionName = permissionName == null ? null : permissionName.trim(); } public String getPermissionResource() { return permissionResource; } public void setPermissionResource(String permissionResource) { this.permissionResource = permissionResource == null ? null : permissionResource.trim(); } }
Role.java:
package com.shiro.demo.model; public class Role { private Long id; private String roleName; private String roles; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName == null ? null : roleName.trim(); } public String getRoles() { return roles; } public void setRoles(String roles) { this.roles = roles == null ? null : roles.trim(); } }
ShiroRelam.java:
package com.shiro.demo.realm; import java.util.List; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.LockedAccountException; 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.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import com.shiro.demo.model.Admin; import com.shiro.demo.service.LoginService; /** * * @description 用于用户的认证和授权 * @author Seven Lee * @date 2017年9月25日 上午10:34:20 * */ public class ShiroRelam extends AuthorizingRealm { @Autowired private LoginService loginService; /** * @description 用户的认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 1.把AuthenticationToken类型转换为UsernamePasswordToken类型 UsernamePasswordToken upToken = (UsernamePasswordToken) token; // 2.从upToken获取到username String username = upToken.getUsername(); // 3.从数据库中通过username查询,认证用户是否存在(调用service) Admin admin = loginService.selectAdminByUsername(username); // 4.判断该用户是否存在,锁定 if (admin == null || "".equals(admin.getUsername())) { throw new UnknownAccountException("该用户名不存在"); } else if (admin.getLocked() == 1) { throw new LockedAccountException("该用户被锁定,请联系管理员"); } // 5.创建SimpleAuthenticationInfo对象,验证该用户的密码是否正确 // 传入的4个参数: // 1.username或者Admin实体对象 // 2.密码 // 3.salt // 4.RealmName(代理对象) SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, admin.getPassword(), ByteSource.Util.bytes(admin.getSalt()), getName()); // 6.返回SimpleAuthenticationInfo对象,认证完成 return info; } /** * @description 用户的授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 1.通过认证返回的SimpleAuthenticationInfo,获取用户名或者用户的实体类对象 String username = (String) principals.getPrimaryPrincipal(); // 2.通过username查询出该认证后的用户拥有什么角色 // sys_admin sys_role admin_role List<String> roles = loginService.selectRolesByUsername(username); // 3.创建SimpleAuthorizationInfo对象,把所有的角色信息封装进该对象 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 4.从数据库中查询出该角色下拥有的权限,eg: 普通用户-->只拥有查看图书的权限,并没有借阅的权限,只要一办会员卡 // ,就可以对图书拥有借阅的权限 // 根据username查询出该认证用户的权限 List<String> permissions = loginService.selectPermissionsByUsername(username); try { info.addRoles(roles); info.addStringPermissions(permissions); } catch (Exception e) { e.printStackTrace(); } // 在这返回给了进行匹配授权的class return info; } }
LoginService.java:
package com.shiro.demo.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.shiro.demo.mapper.AdminMapper; import com.shiro.demo.model.Admin; @Service public class LoginService { @Autowired private AdminMapper adminMapper; /** * @description 通过用户名查询用户信息 * @param username * @return */ public Admin selectAdminByUsername(String username) { return adminMapper.selectAdminByUsername(username); } /** * @description 通过用户名查询该用户拥有的角色名称 * @param username * @return */ public List<String> selectRolesByUsername(String username) { return adminMapper.selectRolesByUsername(username); } /** * @description 根据用户名查询出该用户下的所有权限 * @param username * @return */ public List<String> selectPermissionsByUsername(String username) { return adminMapper.selectPermissionsByUsername(username); } }
AdminMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.shiro.demo.mapper.AdminMapper"> <resultMap id="BaseResultMap" type="com.shiro.demo.model.Admin"> <id column="id" property="id" jdbcType="BIGINT" /> <result column="username" property="username" jdbcType="VARCHAR" /> <result column="password" property="password" jdbcType="VARCHAR" /> <result column="salt" property="salt" jdbcType="VARCHAR" /> <result column="locked" property="locked" jdbcType="INTEGER" /> </resultMap> <!-- 通过用户名查询用户信息 --> <select id="selectAdminByUsername" parameterType="string" resultType="com.shiro.demo.model.Admin"> select * from sys_admin where username = #{username} </select> <!-- 通过用户名查询该用户拥有的角色名称 --> <select id="selectRolesByUsername" parameterType="string" resultType="string"> SELECT sr.roles FROM sys_admin sa LEFT JOIN admin_role ar ON ar.admin_id = sa.id LEFT JOIN sys_role sr ON sr.id = ar.role_id WHERE sa.username = #{username} </select> <!-- 根据用户名查询出该用户下的所有权限 --> <select id="selectPermissionsByUsername" parameterType="string" resultType="string"> SELECT permission_resource FROM sys_permission sp INNER JOIN role_permission rp ON rp.permission_id = sp.id INNER JOIN admin_role ar ON ar.role_id = rp.role_id INNER JOIN sys_admin sa ON sa.id = ar.admin_id WHERE sa.username = #{username} </select> </mapper>
PermissionMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.shiro.demo.mapper.PermissionMapper" > <resultMap id="BaseResultMap" type="com.shiro.demo.model.Permission" > <id column="id" property="id" jdbcType="BIGINT" /> <result column="permission_name" property="permissionName" jdbcType="VARCHAR" /> <result column="permission_resource" property="permissionResource" jdbcType="VARCHAR" /> </resultMap> </mapper>
RoleMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.shiro.demo.mapper.RoleMapper"> <resultMap id="BaseResultMap" type="com.shiro.demo.model.Role"> <id column="id" property="id" jdbcType="BIGINT" /> <result column="role_name" property="roleName" jdbcType="VARCHAR" /> <result column="roles" property="roles" jdbcType="VARCHAR" /> </resultMap> </mapper>
mybatis-config.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- mybatis默认是没有开启延迟加载的 需要手动开启 --> <settings> <!-- 延迟加载 默认false --> <setting name="lazyLoadingEnabled" value="true" /> <!-- 积极加载 默认true --> <setting name="aggressiveLazyLoading" value="false" /> <!--开启缓存 --> <setting name="cacheEnabled" value="true" /> </settings> </configuration>
applicationContext-db.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--数据源配置 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自动扫描mapping.xml文件,**表示迭代查找 --> <property name="mapperLocations" value="classpath*:mapper/*Mapper.xml" /> <!--mybatis配置文件位置 --> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml" /> </bean> <!-- DAO接口所在包名,Spring会自动查找其下的类 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.shiro.demo.mapper" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> </beans>
applicationContext-shiro.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!--注入我们自定的realm --> <property name="realm" ref="shiroRealm" /> <!--注入缓存管理器 --> <property name="cacheManager" ref="cacheManager" /> <!--注入会话管理器 --> <property name="sessionManager" ref="sessionManager" /> <!--注入cookie管理器 --> <property name="rememberMeManager" ref="rememberMeManager" /> </bean> <!--注入cookie管理器 --> <!-- rememberMeManager管理器 --> <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cookie" ref="rememberMeCookie" /> </bean> <!-- 记住我cookie --> <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="rememberMe" /> <!-- 记住我cookie生效时间30天 --> <property name="maxAge" value="2592000" /> </bean> <!-- 会话管理器 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!-- session的失效时长,单位毫秒 --> <property name="globalSessionTimeout" value="600000" /> <!-- 删除失效的session --> <property name="deleteInvalidSessions" value="true" /> </bean> <!-- 缓存管理器 --> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager" /> <!--自定的relam 从数据库访问用户的认证和授权信息 --> <bean id="shiroRealm" class="com.shiro.demo.realm.ShiroRelam"> <property name="credentialsMatcher" ref="credentialsMatcher" /> </bean> <!-- 凭证管理器,设置密码的加密算法和规则 --> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="md5" /> <property name="hashIterations" value="1024" /> </bean> <!-- shiro过滤器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <!-- 如果没有认证将要跳转的登陆地址,http可访问的url, 如果不在表单认证过虑器FormAuthenticationFilter中指, 定此地址就为身份认证地址 --> <property name="loginUrl" value="/login" /> <!-- 没有权限跳转的地址 --> <property name="unauthorizedUrl" value="/noauth" /> <!-- 配置安全规则 --> <property name="filterChainDefinitions"> <value> <!-- 退出拦截,请求logout执行退出操作 --> /logout = logout <!-- 所有已经被认证的用户和记住我的用户全部放行 --> <!-- /** = user --> <!-- 所有的路径都需要被认证才能访问,如果没有认证,会找到loginUrl,loginUrl指向的是controller --> /** = authc </value> </property> </bean> </beans>
applicationContext-tx.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 事务详情 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="select*" read-only="true" /> <tx:method name="find*" read-only="true" /> <tx:method name="get*" read-only="true" /> <tx:method name="query*" read-only="true" /> <tx:method name="*" /> </tx:attributes> </tx:advice> <!--支持基于注解的aspectj --> <aop:aspectj-autoproxy /> <!--aop编程,切入点表达式 确定增强的连接器,从而获得切入点 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.shiro.demo.service..*.*(..)))" /> </aop:config> </beans>
applicationContext-mvc.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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.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"> <!-- 自动扫描且只扫描@Controller --> <context:component-scan base-package="com.shiro.demo.controller" /> <!-- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/> --> <!-- 当在web.xml 中 DispatcherServlet使用 <url-pattern>/</url-pattern> 映射时,能映射静态资源 --> <mvc:default-servlet-handler /> <!-- 可用在springmvc.xml配置文件中使用<mvc:annotation-driven>替代注解处理器和适配器的配置。 --> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg index="0" value="UTF-8" /> </bean> <!-- 格式化json --> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="prettyPrint" value="true" /> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- Jsp视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/" /> <property name="suffix" value=".jsp" /> </bean> <!-- 开启aop对类代理 --> <aop:config proxy-target-class="true" /> <!-- 开启shiro注解支持 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> </beans>
application.properties:
#mysql connector
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/shiro
jdbc.username=root
jdbc.password=root
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--加载配置文件 --> <context:property-placeholder location="classpath:application.properties" /> <!-- 扫描的包路径 去掉mvc的注解 --> <context:component-scan base-package="com.shiro.demo.service" /> <!-- 数据源配置 --> <import resource="spring/applicationContext-db.xml" /> <!-- 事务配置 --> <import resource="spring/applicationContext-tx.xml" /> <!-- 安全框架的配置 --> <import resource="spring/applicationContext-shiro.xml" /> </beans>
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"> <!--Spring入口文件的配置--> <!-- 确定配置文件位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- 配置spring 监听器,加载xml配置文件 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 解决POST请求的中文乱码--> <filter> <filter-name>CharacterEncodingFilter</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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- DispatcherServlet:前端控制器 配置前端控制器servlet --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--加载前端控制器配置文件 上下文配置位置--> <init-param> <!--contextConfigLocation:指定springmvc配置的加载位置, 如果不指定则默认加 载WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml(例如springmvc-servlet.xml)。 --> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc/applicationContext-mvc.xml</param-value> </init-param> <!-- 表示随WEB服务器启动 --> <load-on-startup>1</load-on-startup> </servlet> <!-- 可以拦截二种请求 第一种:拦截固定后缀的url,比如设置为 *.do、*.action, 例如:/user/add.action 此方法最简单,不会导致静态资源(jpg,js,css)被拦截 第二种:拦截所有 设置为/, 例如:/user/add /user/add.action此方法可以实现REST风格的url 很多互联网类型的应用使用这种方式.但是此方法会导致静态文件(jpg,js,css)被拦截后不能正常显示.需要特殊处理 错误设置:拦截所有,设置为/*,此设置方法错误,因为请求到Action, 当action转到jsp时再次被拦截,提示不能根据jsp路径mapping成功. --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- shiro过虑器,DelegatingFilterProx会从spring容器中找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> <!-- <servlet-name>springmvc</servlet-name> --><!-- 所有controller --> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
books.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'books.jsp' starting page</title> </head> <body> <h1>Books Manage Page</h1> <shiro:hasPermission name="book:insert"> <h4> <a href="">新增图书</a> </h4> </shiro:hasPermission> <table> <thead> <tr> <th>图书编号</th> <th>图书名称</th> <th>图书价格</th> <th>操作</th> </tr> </thead> <tbody> <tr> <td>b001</td> <td>爱因斯坦相对论</td> <td>20.5</td> <td><shiro:hasPermission name="book:delete"> <a href="">删除</a> </shiro:hasPermission> <shiro:hasPermission name="book:update"> <a href="">修改</a> </shiro:hasPermission></td> </tr> </tbody> </table> </body> </html>
list.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'list.jsp' starting page</title> </head> <body> <h1> Welcome <shiro:principal></shiro:principal> </h1> <ul> <shiro:hasRole name="book_manager"> <li><a href="/backend_system/manager/book">图书管理</a></li> </shiro:hasRole> <shiro:guest> <li><a href="">加入我们</a></li> </shiro:guest> <li><a href="">请叫我男神</a></li> <li><a href="">就是这么厉害!哈哈哈</a></li> <shiro:hasRole name="menu_manager"> <li><a href="">菜单管理员</a></li> </shiro:hasRole> <li><a href="">登出</a></li> </ul> </body> </html>
login.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> </head> <body> <h1>User Login</h1> <form action="/backend_system/login" method="post"> Username:<input type="text" name="username" /><br /> Password:<input type="password" name="password" /><br /> Remember Me:<input type="checkbox" name="remember" value="1" /><br /> <input type="submit" value="Login" /> </form> </body> </html>
noauth.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'noauth.jsp' starting page</title> </head> <body> <h1>noauth page</h1> </body> </html>
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.shiro.demo</groupId> <artifactId>backend_system</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>backend_system Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <!-- spring --> <spring.version>4.3.4.RELEASE</spring.version> <!-- json --> <jackson.version>2.8.1</jackson.version> <fastjson.version>1.2.17</fastjson.version> <!-- servlet,jstl,jsp --> <servlet-api.version>3.0.1</servlet-api.version> <jsp-api.version>2.0</jsp-api.version> <jstl.version>1.2</jstl.version> <!-- mysql --> <mysql.version>5.1.40</mysql.version> <!-- 连接池 --> <druid.version>1.0.26</druid.version> <mybatis.version>3.3.0</mybatis.version> <!-- mybatis --> <mybatis.spring.version>1.2.3</mybatis.spring.version> <mybatis.mapper.version>3.3.9</mybatis.mapper.version> <!-- log4j的增强slf4j --> <slf4j.version>1.7.7</slf4j.version> <!-- shiro --> <shiro.version>1.2.3</shiro.version> <!-- 缓存 --> <ehcache.version>2.10.3</ehcache.version> </properties> <dependencies> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet-api.version}</version> <scope>provided</scope> </dependency> <!-- jsp --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>${jsp-api.version}</version> <scope>provided</scope> </dependency> <!-- jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> <scope>runtime</scope> </dependency> <!--json start --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!--json end --> <!--spring start --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!--spring end --> <!-- database begin --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis.spring.version}</version> </dependency> <!-- database end --> <!-- shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiro.version}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>${shiro.version}</version> </dependency> <!-- shiro end --> <!--ehcache 缓存配置 --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>${ehcache.version}</version> </dependency> </dependencies> <build> <finalName>backend_system</finalName> </build> </project>