1,shiro对象(Relam)的创建步骤
工具类:目的是自定义(高级定制)授权和认证,
(1)ShiroFilterFactoryBean工厂:——》DefaultWebSecurityManager:-》创建 realm 对象,需要自定义类
这个类的目的是高级定制一个ShiroFilterFactoryBean工厂,生产自定义的Realm,
在这里设置认证和授权
注意:shiro不仅仅要整合spring还要整合thymeleaf
@Configuration public class ShiroConfig { //ShiroFilterFactoryBean工厂:3 @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){ ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); //设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); //添加shiro内置过滤器 /* * anon:无需认证就能访问 * authc:必须认证才能访问 * user:必须拥有记住我功能才能使用 * perms:拥有对某个资源的权限才能访问 * role:拥有某个角色权限才能访问 * */ //拦截 Map<String, String> filterMap=new LinkedHashMap<>(); //这里面的路径是请求路径 filterMap.put("/user/add","perms[user:add]"); filterMap.put("/user/update","authc"); bean.setFilterChainDefinitionMap(filterMap); //设置登录请求 bean.setLoginUrl("/toLogin"); //设置未授权页面 bean.setUnauthorizedUrl("/noauth"); return bean; } //DefaultWebSecurityManager:2 //@Qualifier作用,绑定指定的spring容器里的bean @Bean public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //关联userRealm securityManager.setRealm(userRealm); return securityManager; } //创建 realm 对象,需要自定义类 :1 @Bean(name = "userRealm")//被spring容器接管 public UserRealm userRealm(){ return new UserRealm(); } //整合ShiroDialect:用来整合shiro thymleaf @Bean public ShiroDialect getShiroDialect(){ return new ShiroDialect(); } }
(2)继承抽象类AuthorizingRealm,里面封装的就是自定义的ShiroFilterFactoryBean工厂生产后的产物
在这个类自定义和重写认证和授权
//自定义的 UserRealm public class UserRealm extends AuthorizingRealm { @Autowired UserService userService; //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { System.out.println("执行了=>授权AuthorizationInfo"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //info.addStringPermission("user:add");//授权写死,便于实验 //拿到当前登录的这个对象 Subject subject = SecurityUtils.getSubject(); User currentUser =(User) subject.getPrincipal();//拿到user对象 //设置当前用户的权限,数据从数据库取 info.addStringPermission(currentUser.getPerms()); return info; } //认证 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("执行了=>认证AuthenticationInfo"); UsernamePasswordToken userToken= (UsernamePasswordToken) token; //从真实数据库中拿数据 User user = userService.queryUserByName(userToken.getUsername()); if (user==null){ return null; } //密码认证,shiro做 return new SimpleAuthenticationInfo(user,user.getPwd(),""); } }
到这里shiro的认证和授权就结束了,最后就是结合controller层去去在前端体现了
controller层小demo
@Controller public class MyController { //首页 @RequestMapping({"/","/index"}) public String toIndex(Model model){ model.addAttribute("msg","Hello shiro"); return "index"; } @RequestMapping("user/add") public String add(){ return "user/add"; } @RequestMapping("user/update") public String update(){ return "user/update"; } @RequestMapping("toLogin") public String toLogin(){ return "login"; } @RequestMapping("login") public String login(String username,String password,String remember,Model model){ //获取当前用户 Subject subject= SecurityUtils.getSubject(); if (remember!=null){ subject.isRemembered(); } System.out.println(remember); //封装用户的登陆数据 UsernamePasswordToken token=new UsernamePasswordToken(username,password); try{ subject.login(token);//执行登录方法,如果不报异常就success return "index"; }catch (UnknownAccountException e){//用户名不存在 model.addAttribute("msg","用户名错误"); return "login"; }catch (IncorrectCredentialsException e){//密码不存在 model.addAttribute("msg","密码错误"); return "login"; } } //没有权限提示界面 @RequestMapping("/noauth") @ResponseBody public String unauthorized(){ return "未经授权无法访问此页面"; } //注销 @RequestMapping("logout") public String logout(){ //获取当前用户 Subject currentSubject= SecurityUtils.getSubject(); //注销 currentSubject.logout(); return "redirect:/ "; } }
功能:此demo基本实现了用户的权限管理(如:普通用户,管理员),登陆注销也是结合了shiro,通过判断是否认证动态展示登录和注销,其他功能模块也是通过shiro判断每个用户在后台所拥有的权限,来确定用户所能访问的界面;
demo效果展示
1,游客界面
2,登录界面
3,不同角色访问不同的功能页面
3.1 用户1(add权限)
3.12用户2(update权限)
4,注销(删除subject相当于删除session),返回游客状态
数据库