Spring Boot Shiro

本示例要内容

  • 基于RBAC,授权、认证
  • 加密、解密
  • 统一异常处理
  • redis session支持

介绍

Apache Shiro 是一个功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理。借助Shiro易于理解的API,您可以快速轻松地保护任何应用程序(从最小的移动应用程序到最大的Web和企业应用程序)。

开始使用

添加依赖

    <!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>

RBAC

RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。

创建实体类

  • SysPermission.java
  • SysRole.java
  • UserInfo.java

采用 Jpa 技术会自动生成5张基础表格,分别是:

  • user_info(用户信息表)
  • sys_role(角色表)
  • sys_permission(权限表)
  • sys_user_role(用户角色表)
  • sys_role_permission(角色权限表)

初始化数据

INSERT INTO `user_info` (`uid`,`username`,`name`,`password`,`salt`,`state`) VALUES ('1', 'admin', '管理员', '7430bfdcc59212b32d78aacd42c7fe33', 'md5!@#', 0);
INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (1,0,'用户管理',0,'0/','userInfo:view','menu','userInfo/userList');
INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (2,0,'用户添加',1,'0/1','userInfo:add','button','userInfo/userAdd');
INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (3,0,'用户删除',1,'0/1','userInfo:del','button','userInfo/userDel');
INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (1,0,'管理员','admin');
INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (2,0,'VIP会员','vip');
INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (3,1,'test','test');
INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (1,1);
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (2,1);
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (3,2);
INSERT INTO `sys_user_role` (`role_id`,`uid`) VALUES (1,1);

Shiro配置

首先要配置的是 ShiroConfig 类,Apache Shiro 核心通过 Filter 来实现。使用 Filter是可以通过 URL 规则来进行过滤和权限校验,所以我们需要定义一系列关于 URL 的规则和访问权限。

@Configuration
@Slf4j
public class ShiroConfig { @Autowired
private IgnoreAuthUrlProperties ignoreAuthUrlProperties; @Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
log.info("Shiro过滤器开始处理");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager); // 配置登录页
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后跳转页面
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权界面
shiroFilterFactoryBean.setUnauthorizedUrl("/403"); //拦截器
Map<String, String> filterMap = new LinkedHashMap<>(); //anon:所有url都都可以匿名访问
Set<String> urlSet = new HashSet<>(ignoreAuthUrlProperties.getIgnoreAuthUrl());
urlSet.stream().forEach(temp -> filterMap.put(temp, "anon")); //用户未登录不进行跳转,返回错误信息
Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
filters.put("authc", new MyFormAuthenticationFilter()); //配置退出 过滤器
filterMap.put("/logout", "logout"); //authc:所有url都必须认证通过才可以访问
filterMap.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
} /**
* 凭证匹配器
*
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//散列算法:这里使用MD5算法;
hashedCredentialsMatcher.setHashAlgorithmName("md5");
//散列的次数,比如散列两次,相当于 md5(md5(""));
hashedCredentialsMatcher.setHashIterations(2);
return hashedCredentialsMatcher;
} @Bean
public AuthRealm authRealm() {
AuthRealm authRealm = new AuthRealm();
authRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return authRealm;
} /**
* 安全管理器
*
* @return
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(authRealm());
return securityManager;
} /**
* 启用shiro注解
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
} /**
* 异常处理
*
* @return
*/
@Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver(); Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");
mappings.setProperty("UnauthorizedException", "403");
r.setExceptionMappings(mappings); r.setDefaultErrorView("error");
r.setExceptionAttribute("ex");
return r;
}
}

Shiro 内置的两个主要 Filter介绍

  • anon:所有 url 都都可以匿名访问
  • authc: 需要认证才能进行访问

认证和授权


@Slf4j
public class AuthRealm extends AuthorizingRealm { @Resource
private UserInfoService userInfoService; /**
* 授权
*
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
log.info("调用授权方法");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
UserInfo userInfo = (UserInfo) principals.getPrimaryPrincipal();
for (SysRole role : userInfo.getRoleList()) {
authorizationInfo.addRole(role.getRole());
for (SysPermission p : role.getPermissions()) {
authorizationInfo.addStringPermission(p.getPermission());
}
}
return authorizationInfo;
} /**
* 认证(主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确)
*
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
log.info("调用认证方法");
//获取用户的输入的账号.
String username = (String) token.getPrincipal();
if (username == null) {
throw new AuthenticationException("账号名为空,登录失败!");
} log.info("credentials:" + token.getCredentials());
UserInfo userInfo = userInfoService.findByUsername(username);
if (userInfo == null) {
throw new AuthenticationException("不存在的账号,登录失败!");
} SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
userInfo, //用户
userInfo.getPassword(), //密码
ByteSource.Util.bytes(userInfo.getCredentialsSalt()), //加盐后的密码
getName() //指定当前 Realm 的类名
);
return authenticationInfo;
}
}

登录


/**
* 登录
*
* @param username
* @param password
* @param map 如果出错,回传给前端的map
* @return
*/
@RequestMapping("/login")
public String login(String username, String password, Map<String, Object> map) {
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
Subject subject = SecurityUtils.getSubject();
String msg = "";
try {
subject.login(token);
} catch (UnknownAccountException e) {
msg = "账号不存在!";
} catch (DisabledAccountException e) {
msg = "账号未启用!";
} catch (IncorrectCredentialsException e) {
msg = "密码错误!";
} catch (Throwable e) {
msg = "未知错误!";
} //判断登录是否出现错误
if (msg.length() > 0) {
map.put("msg", msg);
return "/login";
} else {
return "redirect:index";
}
}

方法增加权限验证

    /**
* 用户添加
*
* @return
*/
@RequestMapping("/userAdd")
@RequiresPermissions("userInfo:add")
public String userInfoAdd() {
return "userInfoAdd";
}

这样配置完,执行程序。只有用户拥有userAdd权限才允许访问userAdd接口,否则会提示“未授权”访问

资料

Spring Boot 整合 Shiro实现认证及授权管理的更多相关文章

  1. Spring Boot(十四):spring boot整合shiro-登录认证和权限管理

    Spring Boot(十四):spring boot整合shiro-登录认证和权限管理 使用Spring Boot集成Apache Shiro.安全应该是互联网公司的一道生命线,几乎任何的公司都会涉 ...

  2. (转)Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理

    http://www.ityouknow.com/springboot/2017/06/26/spring-boot-shiro.html 这篇文章我们来学习如何使用 Spring Boot 集成 A ...

  3. Spring Boot (十四): Spring Boot 整合 Shiro-登录认证和权限管理

    这篇文章我们来学习如何使用 Spring Boot 集成 Apache Shiro .安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在 Java 领域一般有 Spring S ...

  4. Spring Boot整合shiro-登录认证和权限管理

    原文地址:http://www.ityouknow.com/springboot/2017/06/26/springboot-shiro.html 这篇文章我们来学习如何使用Spring Boot集成 ...

  5. Spring Boot 整合 Shiro-登录认证和权限管理

    这篇文章我们来学习如何使用 Spring Boot 集成 Apache Shiro .安全应该是互联网公司的一道生命线,几乎任何的公司都会涉及到这方面的需求.在 Java 领域一般有 Spring S ...

  6. Spring Boot 整合 Shiro ,两种方式全总结!

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  7. Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  8. spring boot整合shiro后,部分注解(Cache缓存、Transaction事务等)失效的问题

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/elonpage/article/details/78965176 前言 整合有缓存.事务的sprin ...

  9. spring boot 整合 shiro

    shrio官网:https://shiro.apache.org/ Apache Shiro是一个功能强大且易于使用的Java安全框架,可执行身份验证,授权,加密和会话管理.借助Shiro易于理解的A ...

随机推荐

  1. WPF 中RichTextBox控件用法细讲

    1. 取得已被选中的内容:(1)使用RichTextBox.Document.Selection属性(2)访问RichTextBox.Document.Blocks属性的“blocks”中的Text ...

  2. 关于DDD领域驱动设计的理论知识收集汇总

    原文:关于DDD领域驱动设计的理论知识收集汇总 最近一直在学习领域驱动设计(DDD)的理论知识,从网上搜集了一些个人认为比较有价值的东西,贴出来和大家分享一下: 我一直觉得不要盲目相信权威,比如不能一 ...

  3. Delphi 10.2 Linux 程序开发环境部署的基本步骤(网络连接方式要选择桥接或者是Host Only)

    Delphi 10.2 Linux 程序开发环境部署的基本步骤 http://blog.qdac.cc/?p=4477 升級到 Delphi 10.2 Tokyo 笔记http://www.cnblo ...

  4. 如何开发Office平台上的扩展应用(又称为Office 2013 App,Office 2013 Add-Ins,Apps for Office,Office 应用)

    Office 扩展应用(Office Apps,Office 2013 AddIns,Apps for Office)开发 —— 中文文档 继 VBA 和 VSTO 之后, 微软为 Office 平台 ...

  5. 教你如何在 Visual Studio 2013 上使用 Github

    介绍 我承认越是能将事情变简单的工具我越会更多地使用它.尽管我已经知道了足够的命令来使用Github,但我宁愿它被集成到IDE中.在本教程中,我会告诉你使用Visual Studio 2013如何实现 ...

  6. U盘免疫

    界面如下: 关键部分代码如下: void CImmunityUDlg::OnBnClickedButtonOk() { // TODO: 在此添加控件通知处理程序代码 TCHAR szPath[MAX ...

  7. linux程序机制入门

    GCC环境 类debian系统运行 apt-get install build-essential 安装gcc环境. 编写c语言程序后,运行 gcc ./hello.c 会得到一个名为 a.out 的 ...

  8. LFS Linux From Scratch 笔记2(经验非教程)BLFS

    LFS 完了. 其实还没完,还要装一些其他的组件,系统才算是对人类有用的系统. 正好这里有个BLFS Beyound Linux From Scratch 的教程. 其实,按照现有的可运行的LFS系统 ...

  9. 转载几篇文章URL

    读了百伯在线Jobbole的几篇文章,转给需要的朋友.如下: 产品小设计大体验:http://blog.jobbole.com/39593/ 苹果是一家有工程师的设计公司:Google是一家有设计师的 ...

  10. python中的内置函数(一)

    内置函数:内置函数就是python提供的,可以拿来直接用的函数 作用域相关 locals():返回当前作用域中的名字globals():返回全局作用域中的内容 def func(): print('我 ...