使用Shiro实现认证和授权(基于SpringBoot)
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)的更多相关文章
- Shiro 核心功能案例讲解 基于SpringBoot 有源码
Shiro 核心功能案例讲解 基于SpringBoot 有源码 从实战中学习Shiro的用法.本章使用SpringBoot快速搭建项目.整合SiteMesh框架布局页面.整合Shiro框架实现用身份认 ...
- shiro权限认证与授权
什么是shiro? Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权.加密.会话管理等功能,组成了一个通用的安全认证框架. 为什么要用sh ...
- Spring Boot 整合 Shiro实现认证及授权管理
Spring Boot Shiro 本示例要内容 基于RBAC,授权.认证 加密.解密 统一异常处理 redis session支持 介绍 Apache Shiro 是一个功能强大且易于使用的Java ...
- Shiro的认证与授权
shiro实战教程 一.权限管理 1.1什么是权限管理 基本上涉及到用户参与的系统都需要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以 ...
- Shiro入门之一 -------- Shiro权限认证与授权
一 将Shirojar包导入web项目 二 在web.xml中配置shiro代理过滤器 注意: 该过滤器需要配置在struts2过滤器之前 <!-- 配置Shiro的代理过滤器 --> ...
- ssm整合shiro—实现认证和授权
1.简述 1.1 Apache Shiro是Java的一个安全框架.是一个相对简单的框架,主要功能有认证.授权.加密.会话管理.与Web集成.缓存等. 1.2 Shiro不会去维护用户.维护 ...
- 在web项目中使用shiro(认证、授权)
一.在web项目中实现认证 第一步,在web项目中导入shiro依赖的包 第二步,在web.xml中声明shiro拦截权限的过滤器 <filter> <filter-name> ...
- 详解登录认证及授权--Shiro系列(一)
Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密.Apache Shiro 的首要目标是易于使用和理解.安全有时候是很复杂的,甚至是痛苦的, ...
- Vert.x(vertx) 认证和授权
每个线上系统几乎都是离不开认证和授权的,Vert.x提供了灵活.简单.便捷的认证和授权的支持.Vert.x抽象出了两个核心的认证和授权的接口,一个是 AuthProvider,另一个是User.通过这 ...
随机推荐
- AcWing 841. 字符串哈希
//快速判断两次字符串是不是相等 #include<bits/stdc++.h> using namespace std ; typedef unsigned long long ULL; ...
- JavaScript复习总结一(入门)
总是执着想学各种框架,但忘了基础学好才最重要.每次打开菜鸟教程想重温基础内容,然后就像翻开英文字典,永远在abandon...还是需要做个笔记. 一来加深学习印象,二来等下次打开学习可以知道自己上次学 ...
- python之 '随机'
Q:想生成随机数,用哪个库? import random Q:想生成一个随机整数,范围在[0, 100]之内,怎么弄? >>> random.randint(0, 100) 7 Q: ...
- 记一道简单的re--BUUctf reverse1
1.首先拖进ida里,看到了左面一百多function...还是shift+f12 查看敏感字符串吧 2.发现了这两个比较可疑的字符串,然后双击this is the right flag 进入到了他 ...
- CentOS6.5_x64卸载系统原有MySQL
1.查看系统是否存在MySQL的版本 rpm -qa | grep mysql 2.删除老版本的开头文件和库(rpm -e --nodeps XXX) rpm -e --nodeps mysql-5. ...
- Linux下载安装
博客及下载 https://www.cnblogs.com/nongzihong/p/10475753.html centos镜像 下载 https://blog.csdn.net/sinat_365 ...
- tkinter学习(5)messagebox、pack、grid和place方法
1.messagebox信息弹出框 1.1 代码: import tkinter as tk #导出tk模块 import tkinter.messagebox #导出弹出信息框 #定义窗口.标题.大 ...
- Leet Code 9.回文数
判断一个整数是否是回文数. 题解 普通解法:将整数转为字符串,然后对字符串做判断. ///简单粗暴,看看就行 class Solution { public boolean isPalindrome( ...
- 消息队列(五)--- RocketMQ-消息存储1
问题 : 部署时如何知道自己是 broker 还是 NameServer topic 订阅信息放在哪里 broker 的作用到底是什么 纪录是如何持久化的 群发的时候,是如何储存消息的 send 方法 ...
- windows centos php-beast 安装
https://github.com/imaben/php-beast-binaries windows下 可以直接在这里下载dll 根据自己的php版本 还有是不是线程安全的 来选择下载对应的 放 ...