栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring MVC整合Shiro权限控制的方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring MVC整合Shiro权限控制的方法

Apache Shiro 是一个功能强大且灵活的开放源代码安全框架,可以细粒度地处理认证 (Authentication),授权 (Authorization),会话 (Session) 管理和加密 (cryptography) 等企业级应用中常见的安全控制流程。 Apache Shiro 的首要目标是易于使用和理解。 有时候安全性的流程控制会非常复杂,对开发人员来说是件很头疼的事情,但并不一定如此。 框架就应该尽可能地掩盖复杂性,并公开一个简洁而直观的 API,从而简化开发人员的工作,确保其应用程序安全性。这次我们聊一聊如何在 Spring Web 应用中使用 Shiro 实现权限控制。

功能

Apache Shiro 是一个具有许多功能的综合型应用程序安全框架。 下图为 Shiro 中的最主要的几个功能:

Shiro 的主要目标是“应用安全的四大基石” - 认证,授权,会话管理和加密:

  1. 身份验证:也就是通常所说的 “登录”,为了证明用户的行为所有者。
  2. 授权:访问控制的过程,即确定什么用户可以访问哪些内容。
  3. 会话管理:即使在非 Web 应用程序中,也可以管理用户特定的会话,这也是 Shiro 的一大亮点。
  4. 加密技术:使用加密算法保证数据的安全,非常易于使用。

架构

从整体概念上理解,Shiro 的体系架构有三个主要的概念:Subject (主体,也就是用户),Security Manager (安全管理器)和 Realms (领域)。 下图描述了这些组件之间的关系:

这几大组件可以这样理解:

  1. Subject (主体):主体是当前正在操作的用户的特定数据集合。主体可以是一个人,也可以代表第三方服务,守护进程,定时任务或类似的东西,也就是几乎所有与该应用进行交互的事物。
  2. Security Manager (安全管理器):它是 Shiro 的体系结构的核心,扮演了类似于一把 “伞” 的角色,它主要负责协调内部的各个组件,形成一张安全网。
  3. Realms (领域):Shiro 与应用程序安全数据之间的 “桥梁”。当需要实际与用户帐户等安全相关数据进行交互以执行认证和授权时,Shiro 将从 Realms 中获取这些数据。

数据准备

在 Web 应用中,对安全的控制主要有角色、资源、权限(什么角色能访问什么资源)几个概念,一个用户可以有多个角色,一个角色也可以访问多个资源,也就是角色可以对应多个权限。落实到数据库设计上,我们至少需要建 5 张表:用户表、角色表、资源表、角色-资源表、用户-角色表,这 5 张表的结构如下:

用户表:

id username password
1 张三 123456
2 李四 666666
3 王五 000000

角色表:

id rolename
1 管理员
2 经理
3 员工

资源表:

id resname
1 /user/add
2 /user/delete
3 /compony/info

角色-资源表:

id roleid resid
1 1 1
2 1 2
3 2 3

用户-角色表:

id userid roleid
1 1 1
2 1 2
3 1 3

对应的 POJO 类如下:


public class User {
 private Integer id;
 private String username;
 private String password;
 //getter & setter...
}

public class Role {
 private String id;
 private String rolename;
}

public class Resource {
 private String id;
 private String resname;
}

public class RoleRes {
 private String id;
 private String roleid;
 private String resid;
}

public class UserRole {
 private String id;
 private String userid;
 private String roleid;
}

Spring 与 Shiro 整合的详细步骤,请参阅我的博客 《 Spring 应用中整合 Apache Shiro 》 。 这里补充一下:需要提前引入 Shiro 的依赖,打开mvnrepository.com,搜索 Shiro,我们需要前三个依赖,也就是 Shiro-Core、Shiro-Web 以及 Shiro-Spring,以 Maven 项目为例,在 pom.xml 中的 节点下添加如下依赖:


 org.apache.shiro
 shiro-core
 1.4.0


 org.apache.shiro
 shiro-web
 1.4.0


 org.apache.shiro
 shiro-spring
 1.4.0

在 application-context.xml 中需要这样配置 shiroFilter bean:



 
 
 
 
 
 
 
 
 
 
  
  /static
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
 String loginName = SecurityUtils.getSubject().getPrincipal().toString();
 if (loginName != null) {
 String userId = SecurityUtils.getSubject().getSession().getAttribute("userSessionId").toString();
 // 权限信息对象,用来存放查出的用户的所有的角色及权限
 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
 // 用户的角色集合
 ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal();
  info.setRoles(shiroUser.getRoles());
  info.addStringPermissions(shiroUser.getUrlSet());
 return info;
 }
 return null;
 }
 
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
 String username = (String) token.getPrincipal();
 User user = new User();
 sysuser.setUsername(username);
 try {
 List users = userService.findByNames(user);
  List roleList= userService.selectRoleNameListByUserId(users.get(0).getId());
 if (users.size() != 0) {
 String pwd = users.get(0).getPassword();
 // 当验证都通过后,把用户信息放在 session 里
 Session session = SecurityUtils.getSubject().getSession();
 session.setAttribute("userSession", users.get(0));
 session.setAttribute("userSessionId", users.get(0).getId());
 session.setAttribute("userRoles", org.apache.commons.lang.StringUtils.join(roleList,","));
  return new SimpleAuthenticationInfo(username,users.get(0).getPassword());
 } else {
  // 没找到该用户
 throw new UnknownAccountException();
 }
 } catch (Exception e) {
 System.out.println(e.getMessage());
 }
 return null;
 }
 
 public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
 super.clearCachedAuthorizationInfo(principals);
 }
 
 public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
 super.clearCachedAuthenticationInfo(principals);
 }
 
 public void clearAllCachedAuthorizationInfo() {
 getAuthorizationCache().clear();
 }
 
 public void clearAllCachedAuthenticationInfo() {
 getAuthenticationCache().clear();
 }
 
 public void clearCache(PrincipalCollection principals) {
 super.clearCache(principals);
 }
 
 public void clearAllCache() {
 clearAllCachedAuthenticationInfo();
 clearAllCachedAuthorizationInfo();
 }
}

最后定义一个用户登录的控制器,接受用户的登录请求:

@Controller
public class UserController {
 
 @PostMapping("/login")
 public String login(@Valid User user,BindingResult bindingResult,RedirectAttributes redirectAttributes){
 try {
  if(bindingResult.hasErrors()){
  return "login";
  }
  //使用权限工具进行认证,登录成功后跳到 shiroFilter bean 中定义的 successUrl
  SecurityUtils.getSubject().login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));
  return "redirect:index";
 } catch (AuthenticationException e) {
  redirectAttributes.addFlashAttribute("message","用户名或密码错误");
  return "redirect:login";
 }
 }
 
 @GetMapping("/logout")
 public String logout(RedirectAttributes redirectAttributes ){
 SecurityUtils.getSubject().logout();
 return "redirect:login";
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/141001.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号