七.springmvc+shiro整合
来源:互联网 发布:数据库营销系统 编辑:程序博客网 时间:2024/06/08 13:22
一.mavne的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.tiglle</groupId> <artifactId>springmvc-shiro</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>springmvc-shiro Maven Webapp</name> <url>http://maven.apache.org</url> <!-- 全局属性 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>3.1.2.RELEASE</spring.version> </properties> <dependencies> <!-- springmvc的依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- shiro-spring整合 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency> <!-- https://mvnrepository.com/artifact/jstl/jstl --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- spring开启自动代理需要的包 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.10</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.2.5</version> </dependency> <!-- shiro缓存:结合ehcache --> <!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.6.11</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.4.0</version> </dependency> <!-- scope=provicer:在编译和测试的过程有效,最后生成war包时不会加入,诸如:servlet-api,因为servlet-api,tomcat等web服务器已经存在了,如果再打包会冲突 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>springmvc-shiro</finalName> </build></project>
二.tomcat的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>Archetype Created Web Application</display-name> <!-- Spring MVC 核心 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--以下init-param是自定义SpringMVC的配置文件的位置 --> <!-- 1.可以通过contextConfigLocation来自定义SpringMVC配置文件的位置,如不指定,则默认在WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,此时文件名必须为[<servlet-name>]-servlet.xml,否则会出错 2.如果使用了contextConfigLocation自定义SpringMVC配置文件的位置,spring便不会加载默认/WEB-INF/[<servlet-name>]-servlet.xml文件,需注意 --> <!-- <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> --> <load-on-startup>1</load-on-startup> </servlet> <!-- 拦截设置 --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 此处可以可以配置成*.do,对应struts的后缀习惯 --> <url-pattern>/</url-pattern> </servlet-mapping> <!-- Spring MVC 核心配置结束 --> <!--配置监听器--> <!-- 读取Spring配置文件;applicationContext-shiro.xml --> <context-param> <param-name>contextConfigLocation</param-name> <!-- 如果是监听多个文件,可用‘,’隔开--> <param-value>classpath:applicationContext-shiro.xml</param-value> </context-param> <!--Spring监听器 ApplicationContext 载入 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring字符集过滤器 --> <filter> <filter-name>encoding</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>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- shiro配置 --> <!-- shiro的filter --> <filter> <!-- 任意,但注入spring的时候ref名字要和这个相同,或者通过targetBeanName修改 --> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!-- 是否由servlet容器控制filter的生命周期true:是 --> <init-param> <!-- 覆盖DelegatingFilterProxy的属性默认配置或赋值 --> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> <!-- 修改spring容器注入filter时的id名字,如果不设置,则用filter-name标签的值 --> <init-param> <param-name>targetBeanName</param-name> <param-value>shiroFilter</param-value> </init-param> </filter> <!-- 过滤设置 --> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping></web-app>
三.springmvc的配置文件springmvc-servlet.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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" 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" default-lazy-init="true"> <!-- 开启注解模式驱动 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 扫包 --> <context:component-scan base-package="com.tiglle.*"></context:component-scan> <!-- 开启shiro注解的配置 --> <!-- spring方面:开启aop代理 --> <aop:config proxy-target-class="true"></aop:config> <!-- shiro方面:开启shiro注解支持 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager"/> </bean> <!-- 视图渲染 jsp/freemaker/velocity--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 制定页面存放的路径 --> <property name="prefix" value="/"></property> <!-- 文件的后缀 --> <property name="suffix" value=".jsp"></property> </bean></beans>
四.springmvc和shiro的整合配置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" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" 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" default-lazy-init="true"> <!-- 将web.xml配置的shiroFilter注入到spring容器 id和web.xml的filter-name的值相同,或者和targetBeanName值相同 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 覆盖或赋值ShiroFilterFactoryBean的属性 --> <!-- 指定securityManager --> <property name="securityManager" ref="securityManager"/> <!-- 认证提交地址,如果用户没有认证或认证失效,需要进行表单提交请求此地址进行身份认证(由formAuthentication进行表单认证)默认会自动寻找Web工程根目录下的"/login.jsp"页面 --> <property name="loginUrl" value="/login"/> <!-- 指定没有权限时跳转的页面(或者一个控制器的连接) --> <property name="unauthorizedUrl" value="/refuse.jsp"/> <!-- 指定认证成功的跳转页面,如果不设置,默认跳回上一个url--> <property name="successUrl" value="/WEB-INF/page/main.jsp"/> <!-- shiro的自定义filter配置,会从上往下一个个过滤 --> <property name="filters"> <map> <!-- 所有自定义filter都在这配置,将自定义的FormAuthenticationFilter注入shiro的filter中 --> <entry key="authc" value-ref="formAuthenticationFilter" /> </map> </property> <!-- 过滤规则,从上到下顺序执行,一般将/**放在最下面 --> <property name="filterChainDefinitions"> <value> <!-- /**:所有的地址 anon:匿名访问 所有地址都可以匿名访问--> <!-- /login=authc --> <!-- 指定访问shiro自带的退出登录的连接,shiro会清除session /logout:url logout:shiro自带的退出登陆的方法--> /logout=logout <!-- 首页可以匿名访问 --> /codeImage.jsp=anon <!-- 配置记住我或有认证信息可以访问的连接,user权限就是 --> /main = user <!-- 只有main能在记住我状态和用户信息不为空的情况下能访问,其他连接会往下走authc认证 --> <!-- 需要授权的连接 格式:连接 = perms[权限字符串标示] ,认证失败,会跳转unauthorizedUrl的地址,只有这里配置的连接才会去realm检测权限 缺点:配置太多 解决方法:注解和jsp标签方式配置,注解需要在spring配置文件开启,然后在controller上添加注解 --> <!-- /items/query = perms[item:query] --><!-- 换成使用注解方式配置 --> <!-- /**:所有的地址 authc:需要认证 --> /**=authc </value> </property> </bean> <!-- securityManager安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!-- 使用自定义realm认证 --> <property name="realm" ref="customRealm"/> <!-- 注入缓存管理器,第一次授权会请求realm,后面的授权都不会请求realm --> <property name="cacheManager" ref="cacheManager" /> <!-- 注入session管理器 --> <property name="sessionManager" ref="sessionManager"/> <!-- 注入记住我remeberMeManager管理器 --> <property name="rememberMeManager" ref="rememberMeManager"/> </bean> <!-- 自定义realm --> <bean id="customRealm" class="com.tiglle.shiro.CustomRealm"> <!-- 将凭证匹配器注入到realm--> <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="1"/> </bean> <!-- ehcache缓存管理器 value为ehcache配置文件位置--> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml" /> </bean> <!-- 会话管理,session交给shiro管理 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!-- session的超时时间 毫秒--> <property name="globalSessionTimeout" value="500000"/> <!-- 是否删除已经失效的session数据 --> <property name="deleteInvalidSessions" value="true"/> </bean> <!-- 配置form认证过滤器为自定义的,不配置会使用系统默认的,也可以直接配置系统默认的,并修改账号密码的字段名 --> <bean id="formAuthenticationFilter" class="com.tiglle.shiro.CustomFormAuthenticationFilter"> <!-- 设置表单中账号的input的name值 --> <property name="usernameParam" value="username"/> <!-- 设置表单中密码的input的name值 --> <property name="passwordParam" value="password"/> <!-- 设置记住我的input的name值 --> <property name="rememberMeParam" value="rememberMe"/> </bean> <!-- remenerMeManager管理器,写cookie,取cookie,生成用户信息 --> <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"> <!-- 生成cookie的名字 --> <constructor-arg value="remeberMe" /> <!-- cookie的存在时间(30天) 秒--> <property name="maxAge" value="2592000"/> </bean></beans>
五.ehcache的缓存配置shiro-ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?><ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <!-- diskStore:缓存数据持久化的目录地址 --> <diskStore path="F:\ehcache\store" /> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/></ehcache>
六.自定义reaml的java类和自定义Form认证过滤器:
1.自定义reaml的java类CustomRealm.java:
package com.tiglle.shiro;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.shiro.SecurityUtils;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.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 com.tiglle.bean.User;/** * 自定义realm,覆盖默认realm(需要配置),让授权数据从数据库或其他地方获取 * @author Administrator * */public class CustomRealm extends AuthorizingRealm{ /** * 设置realm的名称,模拟用 */ @Override public void setName(String name) { super.setName("customRealm"); } /** * 认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //token是用户输入的信息 //1.从token中取出用户身份信息,也就是登陆页面的username String username = (String) token.getPrincipal(); System.out.println("---username:"+username); //2.根据用户身份信息从数据库查询用户信息 //.......根据userCode查询数据库 //模拟查了数据库,获得了User对象 User user = new User(); //User user = userService.getUserByUsername(username); //模拟从数据库查询了用户信息,设置用户信息 user.setNickname("小明"); user.setUname(username); user.setUpass("bacbc96d57da0555dc8b58beadbc2d93");//123456+qwert user.setSalt("qwert"); //3.查询不到,请返回null if(user==null){ return null; } //模拟从数据库查询了用户菜单信息 Map<String,String> menus = new HashMap<String, String>(); //Map<String,String> menus = userService.getUserMenusById(user.getId()); menus.put("商品列表","items/query"); menus.put("增加商品","items/toAdd"); menus.put("编辑商品","items/toUpdate"); user.setMenus(menus); //密码 String password = user.getUpass(); //盐 String salt = user.getSalt(); //4.查询到,返回AuthenticationInfo,将user设置进去,盐设置j进去,别忘了在spring配置文件配置凭证匹配器,可以在控制器通过Subject获取 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user,password,ByteSource.Util.bytes(salt),this.getName()); return simpleAuthenticationInfo; } /** * 授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //认证成功后授权 //从principals中获取主身份信息,上面认证成功后存入的省份信息 @SuppressWarnings("unused") User user = (User) principals.getPrimaryPrincipal(); //根据身份信息从数据库查询权限信息 //模拟查询了数据库... //根据身份获得了用户所有的权限信息(List为获取的权限集合) List<String> permission = new ArrayList<String>(); //List<String> permission = userService.findPermissionsByUserId(user.getId()); permission.add("user:add");//=user:create:* permission.add("user:create:1"); permission.add("items:query"); permission.add("items:add"); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); //返回用户所有的权限 simpleAuthorizationInfo.addStringPermissions(permission); return simpleAuthorizationInfo; } /** * 手动清空shiro授权缓存的方法,供service调用 * 清除后,授权会再次请求realm */ public void clearCached(){ PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals(); super.clearCache(principals); }}
2.自定义form认证过滤器的javaCustomFormAuthenticationFilter.java:
package com.tiglle.shiro;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;public class CustomFormAuthenticationFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { // 在这里进行验证码的校检,或者session中数据的校检 //将ServletRequest转为HttpServletRequest HttpServletRequest httpServletRequest = (HttpServletRequest) request; //获取session HttpSession session = httpServletRequest.getSession(); //取出session中的验证码 String code = (String) session.getAttribute("code"); //取出页面的验证码(从ServletRequest获取) String pageCode = httpServletRequest.getParameter("code"); if(pageCode!=null&&!"".equals(pageCode)&&!pageCode.equals(code)){ //如果验证码为空或者验证码与session中的不相等,手动设置异常 httpServletRequest.setAttribute("shiroLoginFailure", "CodeErrorException"); //拒绝访问,不在继续验证账号密码 return true; } //否则,继续验证账号密码(父类方法) return super.onAccessDenied(request, response); }}
七.存放用户信息的实体类User.java:
package com.tiglle.bean;import java.io.Serializable;import java.util.Map;//shiro的remeberMe需要用户身份实体类实现Serializable以便序列化和反序列化public class User implements Serializable{ private String id; private String uname; private String upass; private String salt; private String nickname; private Map<String,String> menus; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public String getUpass() { return upass; } public void setUpass(String upass) { this.upass = upass; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Map<String, String> getMenus() { return menus; } public void setMenus(Map<String, String> menus) { this.menus = menus; } public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; }}
八.springmvc的控制器controller:
1.LoginController.java:
package com.tiglle.controller;import javax.servlet.http.HttpServletRequest;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.UnknownAccountException;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controllerpublic class LoginController { /** * 登陆原理: * 使用FormAuthenticationFilter过虑器实现 ,原理如下: * 将用户没有认证时,请求loginurl进行认证,用户身份和用户密码提交数据到loginurl * FormAuthenticationFilter拦截住取出request中的username和password(两个参数名称是可以配置的) * FormAuthenticationFilter调用realm传入一个token(username和password) * realm认证时根据username查询用户信息(在Activeuser中存储,包括 userid、usercode、username、menus)。 * 如果查询不到,realm返回null,FormAuthenticationFilter向request域中填充一个参数(记录了异常信息) * @throws Exception */ //此控制器只有自定义realm认证失败才会进入,认证成功自动跳转到上一次访问的连接 @RequestMapping("login") public String login(HttpServletRequest request) throws Exception{ //如果登陆失败,shiro把异常放入request中,key为shiroLoginFailure,value为异常的全限定名(包名.类名) String exceptionName = (String) request.getAttribute("shiroLoginFailure"); //根据shiro返回的的异常类名判断异常信息 if(exceptionName!=null){ if(UnknownAccountException.class.getName().equals(exceptionName)){ //账号不存在异常 throw new Exception("账号不存在"); }else if(IncorrectCredentialsException.class.getName().equals(exceptionName)){ //用户名/密码错误 throw new Exception("用户名/密码错误"); }else if("CodeErrorException".equals(exceptionName)){ throw new Exception("验证码错误"); }else{ throw new Exception("未知异常"); } } return "WEB-INF/page/login"; }}
2.MainController.java:
package com.tiglle.controller;import org.apache.shiro.SecurityUtils;import org.apache.shiro.subject.Subject;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import com.tiglle.bean.User;@Controllerpublic class MainController { @RequestMapping("main") public String main(Model model){ //从shiro中获取放入的user信息 Subject subject = SecurityUtils.getSubject(); User user = (User) subject.getPrincipal(); model.addAttribute("user", user); return "/WEB-INF/page/main"; }}
3.ItemsController.java:
package com.tiglle.controller;import org.apache.shiro.authz.annotation.RequiresPermissions;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping("/items")public class ItemsController { //shiro权限注解的使用,只有拥有对应的权限才能执行控制器,否则到配置文件中配置的授权失败的连接(或者报没有权限的异常...) //执行到注解时,会到自定义realm中授权 /** * 到商品列表 * @return */ @RequestMapping("/query") @RequiresPermissions("items:query")//shiro权限注解,表示只有items:query权限才能进此控制器 public String query(){ return "/WEB-INF/page/itemsList"; } /** * 到编辑商品页 * @return */ @RequiresPermissions("items:add")//shiro权限注解,表示只有items:add权限才能进此控制器 @RequestMapping("/toAdd") public String toAdd(){ return "/WEB-INF/page/addItems"; } /** * 确定编辑商品 * @return */ @RequestMapping("/add") @RequiresPermissions("items:add")//shiro权限注解,表示只有items:add权限才能进此控制器 public String add(){ return "/WEB-INF/page/itemsList"; } /** * 到编辑商品页 * @return */ @RequestMapping("/toUpdate") @RequiresPermissions("items:update")//shiro权限注解,表示只有items:update权限才能进此控制器 public String toUpdate(){ return "/WEB-INF/page/updateItems"; } /** * 确定编辑商品 * @return */ @RequestMapping("/update") @RequiresPermissions("items:update")//shiro权限注解,表示只有items:update权限才能进此控制器 public String update(){ return "/WEB-INF/page/itemsList"; }}
4.TestRemoveShiroCache.java:
package com.tiglle.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import com.tiglle.shiro.CustomRealm;@Controllerpublic class TestRemoveShiroCache { /** * 手动情况shiro授权缓存(shiro默认关闭认证缓存,开启授权缓存,授权缓存需配置) * 正常手动清空授权缓存应该在service层,当用户权限改变时调用 */ //注入自定义realm @Autowired private CustomRealm realm; @RequestMapping("clearShiroCache") public String clearShiroCache(){ realm.clearCached(); return "success"; }}
九.webapps下的页面:
1.首页index.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><html><body><centeer><h1>首页面</h1></centeer><a href="main">系统管理</a></body></html>
2.没有权限配置的无权页面refuse.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body>无权访问</body></html>
3.生成验证码的codeImage.jsp:
<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" pageEncoding="utf-8"%> <%! Color getRandColor(int fc,int bc) { Random random = new Random(); if(fc>255) fc=255; if(bc>255) bc=255; int r=fc+random.nextInt(bc-fc); int g=fc+random.nextInt(bc-fc); int b=fc+random.nextInt(bc-fc); return new Color(r,g,b); } %> <% out.clear();//这句针对resin服务器,如果是tomacat可以不要这句 response.setHeader("Pragma","No-cache"); response.setHeader("Cache-Control","no-cache"); response.setDateHeader("Expires", 0); int width=60, height=20; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); Random random = new Random(); g.setColor(getRandColor(200,250)); g.fillRect(0, 0, width, height); g.setFont(new Font("Times New Roman",Font.PLAIN,18)); g.setColor(getRandColor(160,200)); for (int i=0;i<155;i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(12); int yl = random.nextInt(12); g.drawLine(x,y,x+xl,y+yl); } String sRand=""; for (int i=0;i<4;i++){ String rand=String.valueOf(random.nextInt(10)); sRand+=rand; g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110))); g.drawString(rand,13*i+6,16); } // 将认证码存入SESSION session.setAttribute("code",sRand); g.dispose(); ImageIO.write(image, "JPEG", response.getOutputStream()); %>
十.WEB-INF/page下的页面:
1.登陆页面login.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body><form action="login" method="post"><br/> 账号:<input type="text" name="username"><br/> 密码:<input type="password" name="password"><br/> 验证码:<input type="text" name="code"><img alt="验证码" src="/springmvc-shiro/codeImage.jsp" onclick="changeCode(this)"><br/> <input type="checkbox" name="rememberMe"/>自动登陆(记住我)<br/> <input type="submit" value="登陆"></form></body></html><script type="text/javascript"> function changeCode(o){ o.src="/springmvc-shiro/codeImage.jsp?d="+new Date().getTime(); }</script>
2.登陆成功的主页面main.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!-- 使用shiro的jsp标签需要的 --><%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>系统管理</title></head><body><h3><c:if test="${empty user }"><a href="login">请登录</a></c:if><c:if test="${not empty user }">欢迎您:${user.nickname }</c:if> </h3><center> <h1>系统管理</h1> <!-- shiro的jsp权限判断标签 --> <!-- 执行到此标签处会到自定义realm中检测权限--> <shiro:hasPermission name="items:query"> <h4>拥有到商品列表的权限</h4> </shiro:hasPermission> <shiro:hasPermission name="items:add"> <h4>拥有添加商品的权限</h4> </shiro:hasPermission> <shiro:hasPermission name="items:update"> <h4>拥有修改商品的权限</h4> </shiro:hasPermission> <c:forEach items="${user.menus }" var="menu"> <h2><a href="${menu.value }">${menu.key }</a></h2> </c:forEach> <!-- jsp的shiro标签 --> <code> 标签名称 标签条件(均是显示标签内容) shiro:authenticated 登录之后 shiro:notAuthenticated 不在登录状态时 shiro:guest 用户在没有RememberMe时 shiro:user 用户在RememberMe时 shiro:hasAnyRoles name="abc,123" 在有abc或者123角色时 shiro:hasRole name="abc" 拥有角色abc shiro:lacksRole name="abc" 没有角色abc shiro:hasPermission name="abc" 拥有权限资源abc shiro:lacksPermission name="abc" 没有abc权限资源 shiro:principal 显示用户身份名称 shiro:principal property="username" 显示用户身份中的属性值 </code> <!-- shiro --></center><a href="logout">退出登陆</a><a href="clearShiroCache">清除shiro缓存</a></body></html>
3.添加商品的页面addItems.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body><center> <h1>增加商品页</h1> <h2><a href="add">确定增加</a></h2></center></body></html>
4.更新商品的页面updateItems.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body><center> <h1>编辑商品页</h1> <h2><a href="update">确定编辑</a></h2></center></body></html>
5.商品列表页面itemsList.jsp:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body><center> <h1>商品列表页</h1></center></body></html>
阅读全文
1 0
- 七.springmvc+shiro整合
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- springmvc整合shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- Springmvc整合shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- SpringMVC整合Shiro
- Unity中实现UI跟随
- #2 内建的助手
- wpa_supplicant软件架构分析
- 【旧资料整理】linux rm 安全
- Angular 模块
- 七.springmvc+shiro整合
- bzoj 1051: [HAOI2006]受欢迎的牛
- 带权并查集 How Many Answers Are Wrong
- File类遍历目录代码示例
- LeetCode Week18: Sicily Test
- 【旧资料整理】笔记本无线共享路由器网络连接方法要点总结
- 51nod 1717 好数
- Android如何将数据返回给上一个活动
- 【旧资料整理】ubuntu 10.04 个性配置