Apache Shiro是一个功能强大且易于使用的Java安全框架,它为开发人员提供了一种直观,全面的身份验证,授权,加密和会话管理解决方案。下面是在SpringBoot中使用Shiro进行认证和授权的例子,代码如下:

pom.xml

导入SpringBoot和Shiro依赖:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.2</version>
</dependency>
</dependencies>

也可以直接导入Apache Shiro提供的starter:

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
</dependency>

Shiro配置类

package com.cf.shiro1.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
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.HashMap;
import java.util.Map; @Configuration
public class ShiroConfig { @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //设置安全管理器
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager); //设置未认证(登录)时,访问需要认证的资源时跳转的页面
shiroFilterFactoryBean.setLoginUrl("/loginPage"); //设置访问无权限的资源时跳转的页面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorizedPage"); //指定路径和过滤器的对应关系
Map<String, String> filterMap = new HashMap<>();
//设置/user/login不需要登录就能访问
filterMap.put("/user/login", "anon");
//设置/user/list需要登录用户拥有角色user时才能访问
filterMap.put("/user/list", "roles[user]");
//其他路径则需要登录才能访问
filterMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
} @Bean
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("realm") Realm realm) {
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(realm);
return defaultWebSecurityManager;
} @Bean
public Realm realm() {
MyRealm realm = new MyRealm();
//使用HashedCredentialsMatcher带加密的匹配器来替换原先明文密码匹配器
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//指定加密算法
hashedCredentialsMatcher.setHashAlgorithmName("MD5");
//指定加密次数
hashedCredentialsMatcher.setHashIterations(3);
realm.setCredentialsMatcher(hashedCredentialsMatcher);
return realm;
}
}

自定义Realm

package com.cf.shiro1.config;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set; public class MyRealm extends AuthorizingRealm {
/**
* 授权
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
Object username = principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.setRoles(getRoles(username.toString()));
return simpleAuthorizationInfo;
} /**
* 认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; String username = token.getUsername();
Map<String, Object> userInfo = getUserInfo(username);
if (userInfo == null) {
throw new UnknownAccountException();
} //盐值,此处使用用户名作为盐
ByteSource salt = ByteSource.Util.bytes(username); SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, userInfo.get("password"), salt, getName());
return authenticationInfo;
} /**
* 模拟数据库查询,通过用户名获取用户信息
*
* @param username
* @return
*/
private Map<String, Object> getUserInfo(String username) {
Map<String, Object> userInfo = null;
if ("zhangsan".equals(username)) {
userInfo = new HashMap<>();
userInfo.put("username", "zhangsan"); //加密算法,原密码,盐值,加密次数
userInfo.put("password", new SimpleHash("MD5", "123456", username, 3));
}
return userInfo;
} /**
* 模拟查询数据库,获取用户角色列表
*
* @param username
* @return
*/
private Set<String> getRoles(String username) {
Set<String> roles = new HashSet<>();
roles.add("user");
roles.add("admin");
return roles;
}
}

Controller

package com.cf.shiro1.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/user")
public class UserController { /**
* 登录
* @param username
* @param password
* @return
*/
@RequestMapping("/login")
public String userLogin(String username, String password) {
String result; //获取当前用户
Subject currentUser = SecurityUtils.getSubject(); //用户是否已经登录,未登录则进行登录
if (!currentUser.isAuthenticated()) {
//封装用户输入的用户名和密码
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password); try {
//登录,进行密码比对,登录失败时将会抛出对应异常
currentUser.login(usernamePasswordToken);
result = "登录成功";
} catch (UnknownAccountException uae) {
result = "用户名不存在";
} catch (IncorrectCredentialsException ice) {
result = "密码错误";
} catch (LockedAccountException lae) {
result = "用户状态异常";
} catch (AuthenticationException ae) {
result = "登录失败,请与管理员联系";
}
} else {
result = "您已经登录成功了";
} return result;
} @RequestMapping("/list")
public String userList() {
return "访问我需要登录并且需要拥有user角色!";
}
}

使用Shiro实现认证和授权(基于SpringBoot)的更多相关文章

  1. Shiro 核心功能案例讲解 基于SpringBoot 有源码

    Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...

  2. shiro权限认证与授权

    什么是shiro? Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权.加密.会话管理等功能,组成了一个通用的安全认证框架. 为什么要用sh ...

  3. Spring Boot 整合 Shiro实现认证及授权管理

    Spring Boot Shiro 本示例要内容 基于RBAC,授权.认证 加密.解密 统一异常处理 redis session支持 介绍 Apache Shiro 是一个功能强大且易于使用的Java ...

  4. Shiro的认证与授权

    shiro实战教程 一.权限管理 1.1什么是权限管理 基本上涉及到用户参与的系统都需要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以 ...

  5. Shiro入门之一 -------- Shiro权限认证与授权

    一  将Shirojar包导入web项目 二 在web.xml中配置shiro代理过滤器 注意: 该过滤器需要配置在struts2过滤器之前 <!-- 配置Shiro的代理过滤器 -->  ...

  6. ssm整合shiro—实现认证和授权

    1.简述 1.1    Apache Shiro是Java的一个安全框架.是一个相对简单的框架,主要功能有认证.授权.加密.会话管理.与Web集成.缓存等. 1.2   Shiro不会去维护用户.维护 ...

  7. 在web项目中使用shiro(认证、授权)

    一.在web项目中实现认证 第一步,在web项目中导入shiro依赖的包 第二步,在web.xml中声明shiro拦截权限的过滤器 <filter> <filter-name> ...

  8. 详解登录认证及授权--Shiro系列(一)

    Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密.Apache Shiro 的首要目标是易于使用和理解.安全有时候是很复杂的,甚至是痛苦的, ...

  9. Vert.x(vertx) 认证和授权

    每个线上系统几乎都是离不开认证和授权的,Vert.x提供了灵活.简单.便捷的认证和授权的支持.Vert.x抽象出了两个核心的认证和授权的接口,一个是 AuthProvider,另一个是User.通过这 ...

随机推荐

  1. python如何用sqlalchemy操作数据库

    工具:mysql  python sqlalchemy ---------------------------------------- 准备工作: 1.安装mysql 如果是window环境请参考 ...

  2. 喵星之旅-狂奔的兔子-基于docker的rabbitmq安装

    docker安装参考:喵星之旅-狂奔的兔子-docker安装和基本使用 一.查询镜像名称 由于我们要安装的是有web管理页面的,不能直接拉取,需要指定版本. 登录docker仓库查询:https:// ...

  3. markdown pic

    Markdown 图片 Markdown 图片语法格式如下: ![alt 属性文本](图片地址) ![alt 属性文本](图片地址 "可选标题") 开头一个感叹号 ! 接着一个方括 ...

  4. HahMap相关问题

    概述 文章对HashMap的部分细节进行介绍,JDK1.7之前有可能出现环形表的问题,而1.7之后进行了改进,文章对环形表现象的出现进行了解析,然后对HashMap注意的几个问题进行了解答. Hash ...

  5. 507,介绍一下标准的css盒子模型?低版本ie的盒子模型有什么不同的?

    有两种,IE盒子模型,另外是W3C盒子模型: 盒模型都包括:内容(content),填充(padding),边界(margin),边框(border): 区别:IE的content部分吧border和 ...

  6. sqlmap+burpsuit

    sqlmap可以批量扫描burpsuit导出的requests日志文件,从而进行批量扫描是否存在SQL注入. 首先设置burpsuit记录代理的Requests 把记录的日志文件保存在sqlmap的目 ...

  7. SQL语句,pymysql模块,sql注入问题

    一.完整版SQL语句的查询 select distinct post,avg(salary) from table where id > 1 group by post` having avg( ...

  8. Go语言基础之os

    文章引用自 package os import "os" os包提供了操作系统函数的不依赖平台的接口.设计为Unix风格的,虽然错误处理是go风格的:失败的调用会返回错误值而非错误 ...

  9. 使用Log4net记录日志(非常重要)

    使用Log4net记录日志   首先说说为什么要进行日志记录.在一个完整的程序系统里面,日志系统是一个非常重要的功能组成部分.它可以记录下系统所产生的所有行为,并按照某种规范表达出来.我们可以使用日志 ...

  10. JZOJ5915 [2018NOIP模拟] 明日之星(广义后缀自动机,线段树)

    题目描述 给定一棵树,每个节点有一个权值 \(a_i\) 和一个字符串 \(s_i\). q组询问,每次询问一个字符串 S 和两个节点x,y: 求x到y路径上每个节点的字符串在 S 中出现的次数乘上各 ...