Shiro免密登录

2023-11-11

Shiro免密登录

代码构成

1.创建枚举类LoginType

/**
 * 登录类型
 */
public enum LoginType {
    PASSWORD("password"), // 密码登录
    NOPASSWD("nopassword"); // 免密登录
    private String code;// 状态值
 
    private LoginType(String code) {
        this.code = code;
    }
 
    public String getCode() {
        return code;
    }
}

2.自定义token类CustomeToken,继承UsernamePasswordToken类,通过构造方法区分密码登录和免密登录。

/**
 * 自定义token 继承UsernamePasswordToken
 * 
 */
public class CustomeToken extends UsernamePasswordToken {
    private static final long serialVersionUID = -2564928913725078138L;
 
    private LoginType type;
 
 
    public CustomeToken() {
        super();
    }
 
 
    public CustomeToken(String username, String password, LoginType type, boolean rememberMe, String host) {
        super(username, password, rememberMe, host);
        this.type = type;
    }
 
    /**
     * 免密登录
     */
    public CustomeToken(String username) {
        super(username, "", false, null);
        this.type = LoginType.NOPASSWD;
    }
 
    /**
     * 账号密码登录
     */
    public CustomeToken(String username, String password) {
        super(username, password, false, null);
        this.type = LoginType.PASSWORD;
    }
 
    public LoginType getType() {
        return type;
    }
 
 
    public void setType(LoginType type) {
        this.type = type;
    }
}

3.修改自定义的CustomeRealm,这个类继承了AuthorizingRealm类。

@Component
public class CustomeRealm extends AuthorizingRealm {
 
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String loginName = (String)principals.getPrimaryPrincipal();
		System.out.println("调用授权验证:" + loginName);
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		//用户权限列表
		//TODO此处的用户权限列表可以根据自己实际业务进行数据库数据查询
		Set<String> permsSet = new HashSet<>();
		authorizationInfo.setStringPermissions(permsSet);
        return authorizationInfo;
	}
 
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
 
		//从传过来的token获取到用户名
		String principal = (String)token.getPrincipal();
		System.out.println("调用认证 ===> " + principal);
		
		ByteSource salt = ByteSource.Util.bytes(principal);
		String newPs = new SimpleHash("MD5","123",salt,1024).toHex();
		//return new SimpleAuthenticationInfo(principal,newPs,salt,this.getName());
		
		return new SimpleAuthenticationInfo(principal, null, this.getName());
	}
}

4.自定义CostomeCredentialsMatch类继承HashedCredentialsMatcher类,覆写其中的doCredentialsMatch方法,将token强转为自定义token,若loginType是免密登录,则直接返回true,否则执行父类比对。

public class CustomCredentialsMatch extends HashedCredentialsMatcher {

    @Override
    public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) {
        CustomToken tk = (CustomToken) authcToken;
        if(tk.getType().equals(LoginType.NOPASSWD)){
            return true;
        }
        boolean matches = super.doCredentialsMatch(authcToken, info);
        return matches;
    }

}

5.ShiroConfig文件

@Configuration
public class ShiroConfig{
	
	//1.创建shiroFilter,负责拦截所有请求
	@Bean
	public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		//filter设置安全管理器
		shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
		Map<String,String> map = new HashMap<String,String>();
		map.put("/initindex","anon");
		map.put("/sys/**","anon");
		map.put("/app/**","anon");
		
		//authc 请求这个资源需要认证
		map.put("/**","authc");
		
		//默认认证界面路径 --- 当认证不通过时跳转
		shiroFilterFactoryBean.setLoginUrl("/login");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
		return shiroFilterFactoryBean;
	}
	
	//2.创建安全管理器
	@Bean("securityManager")
	public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") Realm realm){
		DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
		//给安全管理器设置自定义Realm
		defaultWebSecurityManager.setRealm(realm);
		
		return defaultWebSecurityManager;
	}
	
	//3.创建自定义Realm
	@Bean
	public Realm getRealm(CustomCredentialsMatch matcher){
	
		CustomerRealm customerRealm = new CustomerRealm();
		customerRealm.setCredentialsMatcher(matcher);
		
		//开启缓存管理
		customerRealm.setCacheManager(new EhCacheManager());
		customerRealm.setCachingEnabled(true);  //开启全局缓存
		customerRealm.setAuthenticationCachingEnabled(true);  //开启认证缓存
		customerRealm.setAuthenticationCacheName("authenticationCache");
		customerRealm.setAuthorizationCachingEnabled(true);  //开启授权缓存
		customerRealm.setAuthorizationCacheName("authorization");
		
		return customerRealm;
	}
	
	
	/**
	* 方法名:
	* 功能:凭证匹配器
	* 描述:指定shiro加密方式和次数
	*/
	@Bean(name = "customCredentialsMatch")
	public CustomCredentialsMatch hashedCredentialsMatch(){
		CustomCredentialsMatch hashedCredentialsMatch = new CustomCredentialsMatch();
		hashedCredentialsMatch.setHashAlgorithmName("MD5");
		hashedCredentialsMatch.setHashIterations(1024);
		return hashedCredentialsMatch;
	}
	
	@Bean("lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
		return new LifecycleBeanPostProcessor();
	}
	
	/**
	* 开启shiro aop注解支持,使用代理方式; 所以需要开启代码支持; Controller才能使用@RequiresPermissions
	*
	*/
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}
	
}

6.模拟用户登陆

@RequestMapping("/initindex")
public void loginTest(HttpServletRequest request,
						HttpServletResponse response){
	Subject subject = SecurityUtils.getSubject();
	//密码登录
	//CustomToken token = new CustomToken("zhangsan",123);
	//无密登录
	CustomToken token = new CustomToken("zhangsan");
	token.setRememberMe(true);
	subject.login(token);
	
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Shiro免密登录 的相关文章

随机推荐

  • 输出三角形

    输入一个数 输出对应层数的三角形 m eval input for i in range 1 m 1 for x in range 1 m 1 i print end for j in range 1 2 i print end print
  • Flask快速入门与进阶

    欢迎来到Flask的世界 1 Flask介绍 Flask诞生于2010年 是Armin ronacher 用 Python 语言基于 Werkzeug 工具箱编写的轻量级Web开发框架 Flask是一个使用 Python 编写的轻量级 We
  • error while loading shared libraries: libopencv_core.so.2.4: cannot open shared object file: No such

    如何解决error while loading shared libraries libopencv core so 2 4 cannot open shared object file No such file or directory
  • Python3.6下安装opencv

    opencv安装问题 1 首先你要有个python 安装Python环境后 推荐使用Anaconda 因为我3 6的python版本 在Anaconda环境下装的opencv 2 anaconda下自带有numpy等依赖包 你可以直接 pi
  • 走进Linux(一切皆文件)

    文章目录 悄悄来到Linux 进入Linux 已配置完毕 一切皆文件 常用的命令 根据实例来升级 文件 用户 进程 process 磁盘分区 disk 端口号 其他 悄悄来到Linux 在我们熟悉了Windows的骚操作以后 我们也可以尝试
  • Element UI 使用Tree组件设置节点勾选问题

    Element UI 使用Tree组件设置节点勾选问题 问题分析 1 设置 tree复选框 check strictly false 默认 父子关联 选中父级 勾选所有子选项 取消父级选中 同时取消子选项勾选 选中子选项 父选项变为半选中状
  • Java中的String的一些常用方法

    家人们好 目录 字符 字节与字符串 字符与字符串 获取指定位置的字符 字符串与字符数组的转换 给定字符串一个字符串 判断其是否全部由数字所组成 字节与字符串 实现字符串与字节数组的转换处理 字符串常见操作 字符串比较 不区分大小写比较 观察
  • 灯光 (1)平行光(Directional Light)

    1 平行光 Directional Light 定义一个光线方向向量而不是位置向量来模拟一个定向光 着色器的计算基本保持不变 但这次我们将直接使用光的direction向量而不是通过position来计算lightDir向量 struct
  • C++类中const修饰的函数与重载

    一 重载的定义 重载声明是指在同一个作用域内 可以声明几个功能类似的同名函数 但是这些同名函数的形式参数 指参数的个数 类型或者顺序 必须不同 返回值的类型不同 不能作为重载函数的判断依据 如下举例一组重载函数 void fun int a
  • FTL 入门

    最近的项目中用的是ftl文件而不是传统的jsp 于是上网查了一下 感觉这是个好东西 于是准备记录下来 以下摘自百度百科 1 概念 FreeMarker是一款模板引擎 即一种基于模板和要改变的数据 并用来生成输出文本 HTML网页 电子邮件
  • AttributeError: ‘function‘ object has no attribute ‘_name_‘

    在运行python的下面代码时 def log func def wrapper args kw print call s func name return func args kw return wrapper log def now p
  • layui table单元格事件修改值

    事件中的 this相当于document getElementById id 替代方法就是将原本 document getElementById id InnerHTML 填充代码 替换成 id html 填充代码
  • 数据结构_队列

    队列类似于日常生活中的排队 它也是一种特殊的线性表 队列和栈有相反的逻辑 但是却属于同类结构 文章目录 队列的介绍 队列的结构 队列的实现 完整代码及测试程序 循环队列 循环队列的介绍 循环队列的实现 完整代码 队列的介绍 定义 队列是一种
  • Truechain运用docker镜像搭建TrueChain测试私有环境

    https github com truechain wiki blob master task list task 20180917 md 安装docker Mac参考https blog csdn net jiang xinxing a
  • 图像边缘检测——一阶微分算子 Roberts、Sobel、Prewitt、Kirsch、Robinson(Matlab实现)

    图像边缘一般指图像的灰度变化率最大的位置 成因主要如下 1 图像灰度在表面法向变化不连续 2 图像中物体在空间上的深度不一致 3 在光滑的表面上颜色不一致 4 图像中物体的光影 边缘检测指的是从图像中检测边缘点和边缘段 并且描述边缘方向的过
  • 无重复字符的最长字串

    1 给定一个字符串 s 请你找出其中不含有重复字符的 最长子串的长度 代码展示 class Solution public int lengthOfLongestSubstring String s int n s length if n
  • PMAC网络USB设置

    一 连接到PMAC 在默认情况下 Power PMAC有一个IP地址为192 168 0 200 没有互联网连接 要安装所需的软件包并获得时间 您的PMAC将需要一个internet连接 为了建立你的网络连接 可以一个u盘上放一个文件夹 P
  • MYSQL数据库基本操作——DDL

    MYSQL DDL 何为DDL 对数据库的常用操作 对表结构的操作 创建表 表的其它操作 修改表结构 何为DDL DDL是数据定义语言 包括对数据库的常用操作 对表结构的常用操作 修改表结构三部分 通俗来讲 就是不包括对表内数据进行操作的所
  • 解救开发人员写文档的痛苦

    开发人员的痛苦 接手前人的项目 没有接口文档 只能看代码学习 接口文档用txt word markdown写 编写特别麻烦 写出来的文档也不美观 多层级的参数 子参数 写起来麻烦 不知道怎么表达更好 有的文档需要图文并茂 需要代码示例 需要
  • Shiro免密登录

    Shiro免密登录 代码构成 代码构成 1 创建枚举类LoginType 登录类型 public enum LoginType PASSWORD password 密码登录 NOPASSWD nopassword 免密登录 private