本文共 9263 字,大约阅读时间需要 30 分钟。
承接上一篇博客:
这是下一篇博客: 首先要说的是,这个项目实战是参考自黑马,可以去对应视频看一看: 接下来按照这几个步骤首先要了解,shiro有着几个核心api
subject:用户主体(把操作交给SecurityManager)
SecurityManager:安全管理器(关联Realm) Realm:shiro连接数据的桥梁
然后是在pox里导入shiro的依赖
org.apache.shiro shiro-spring 1.4.0
并且自定义一个Realm类
package com.example.shiro;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;/** * 自定义的Realm shiro有两个功能,认证和授权,所以刚好实现这两个功能 */public class UserRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行授权逻辑"); return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { System.out.println("执行认证逻辑"); return null; }}
然后是创建shiro类
package com.example.shiro;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ShiroConfig { /** * 创建Realm bean会让方法返回的对象放入到spring的环境,以便使用 */ @Bean(name = "userRealm") public UserRealm getRealm(){ return new UserRealm(); } /** * 创建DefaultWebSecurityManager */ //这里的传参有点特殊可以调用一个注解,这里有个细节,想看看注解区不区分大小写 //实测,会报错。。。所以是区分大小写的 // @Qualifier 注释指定注入 Bean 的名称,是用来消除歧义的 //这里也要有Bean @Bean(name = "defaultWebSecurityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager(); //关联realm,并且这个是需要传参的 defaultWebSecurityManager.setRealm(userRealm); return defaultWebSecurityManager; //感觉和直接return一个 new的一样吧 之所以不直接return是因为,会调用一个 //关联realm的方法 } /** * 创建shiroFilterFactoryBean */ //也是需要注解和参数的 public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean(); //设置一个安全管理器来关联SecurityManager shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); return shiroFilterFactoryBean; }}
位置如下
使用shiro内置过滤器实现页面拦截 先在templates下创建用户添加add.html和用户更新的界面update.html add.html用户添加页面 用户添加
update.html
用户更新页面 用户更新
并且修改test.html 让他能跳转到这两个其他的界面
test.html测试用的
进入用户添加功能:用户添加进入用户更新功能:用户更新
结构如下:
然后就可以启动application 浏览器输入 但是会发现,点击用户添加或者用户更新,都会出现 解决方法的话,主要是在于这个项目是用spring写的,所以都是用的自动装配,所以直接在controller那边新加入这两个就可以了UserController新添加的类
//用户的增加 @RequestMapping("/add") public String add(){ System.out.println("UserController.add()"); //这里返回的是路径 //所以是需要删除ResponseBody return "user/add"; } //用户的更新 @RequestMapping("/update") public String update(){ System.out.println("UserController.update()"); //同理返回路径 return "user/update"; }
并把test再修改一下
测试用的
进入用户添加功能:用户添加进入用户更新功能:用户更新
再开始正式添加shiro内置过滤器,先介绍一下,他有五种:
anon:无序认证(登录)就可以访问
authc:必须认证才可以访问 user:如果使用rememberMe的功能可以直接访问 perms:该资源必须得到资源权限才可以访问 role:该资源必须得到角色权限才可以访问
然后往shiroConfig里添加数据
package com.example.shiro;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;import java.util.Map;@Configurationpublic class ShiroConfig { /** * 创建Realm bean会让方法返回的对象放入到spring的环境,以便使用 */ @Bean(name = "userRealm") public UserRealm getRealm(){ return new UserRealm(); } /** * 创建DefaultWebSecurityManager */ //这里的传参有点特殊可以调用一个注解,这里有个细节,想看看注解区不区分大小写 //实测,会报错。。。所以是区分大小写的 // @Qualifier 注释指定注入 Bean 的名称,是用来消除歧义的 //这里也要有Bean @Bean(name = "defaultWebSecurityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager(); //关联realm,并且这个是需要传参的 defaultWebSecurityManager.setRealm(userRealm); return defaultWebSecurityManager; //感觉和直接return一个 new的一样吧 之所以不直接return是因为,会调用一个 //关联realm的方法 } /** * 创建shiroFilterFactoryBean */ //也是需要注解和参数的 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean(); //设置一个安全管理器来关联SecurityManager shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); //添加shiro内置过滤器 //先创建一个Map集合 MapfilterMap=new LinkedHashMap (); //然后往里面添加东西 filterMap.put("/add","authc"); filterMap.put("/update","authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; }}
然后启动这个application
会发现这个错误: 拦截成功会默认到这个jsp文件 所以需要进行修改,到我们让他跳转的页面 所以有一个新写的login方法登录页面 登录页面
然后对应的改写UserController和在shiro里面增加对应的功能
UserControllerpackage com.example.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;@Controllerpublic class UserController { //测试方法 @ResponseBody @RequestMapping("/hello") public String hello(){ System.out.println("UserController.hello()"); return "ok"; } //在使用 @RequestMapping后,返回值通常解析为跳转路径, // 但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body //测试thymeleaf //所以注意的是 这边是没加@ResponseBody,也就是他就是一个跳转路径,所以要创建一个test @RequestMapping("/testThymeleaf") public String testThymeleaf(Model model){ //把数据存入到model中 model.addAttribute("name","wzw"); //返回界面 return "test"; } //用户的增加 @RequestMapping("/add") public String add(){ System.out.println("UserController.add()"); //这里返回的是路径 //所以是需要删除ResponseBody return "user/add"; } //用户的更新 @RequestMapping("/update") public String update(){ System.out.println("UserController.update()"); //同理返回路径 return "user/update"; } //用户的的登录 @RequestMapping("/login") public String login(){ System.out.println("UserController.login()"); //同理返回路径 return "login"; }}
shrioConfig
package com.example.shiro;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;import java.util.Map;@Configurationpublic class ShiroConfig { /** * 创建Realm bean会让方法返回的对象放入到spring的环境,以便使用 */ @Bean(name = "userRealm") public UserRealm getRealm(){ return new UserRealm(); } /** * 创建DefaultWebSecurityManager */ //这里的传参有点特殊可以调用一个注解,这里有个细节,想看看注解区不区分大小写 //实测,会报错。。。所以是区分大小写的 // @Qualifier 注释指定注入 Bean 的名称,是用来消除歧义的 //这里也要有Bean @Bean(name = "defaultWebSecurityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){ DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager(); //关联realm,并且这个是需要传参的 defaultWebSecurityManager.setRealm(userRealm); return defaultWebSecurityManager; //感觉和直接return一个 new的一样吧 之所以不直接return是因为,会调用一个 //关联realm的方法 } /** * 创建shiroFilterFactoryBean */ //也是需要注解和参数的 //这里也是需要bean注解的 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean(); //设置一个安全管理器来关联SecurityManager shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); //添加shiro内置过滤器 //先创建一个Map集合 MapfilterMap=new LinkedHashMap (); //然后往里面添加东西 filterMap.put("/add","authc"); filterMap.put("/update","authc"); /** * 修改调整的登录页面 */ //然后这个跳转的页面,就是需要control来进行自动装入这个页面 shiroFilterFactoryBean.setLoginUrl("/login"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); return shiroFilterFactoryBean; }}
这样就可以了
转载地址:http://tsfen.baihongyu.com/