springsecurity6配置三

news/2024/7/5 3:49:12

springsecurity配置多种登录方式,比如手机验证码登录、邮箱登录、微信小程序登录等,下面就以微信小程序登录为例进行讲解。

一、小程序用户实体实现springsecurity中的UserDetails接口

package com.school.information.core.security.entity;

import com.alibaba.fastjson.annotation.JSONField;
import com.school.information.entity.SysWechatUserEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class WechatAppUser implements UserDetails {
    /**
     * 微信小程序返回的session_key
     */
    private String sessionKey;

    /**
     * 小程序的基本信息
     *
     * @return
     */
    private SysWechatUserEntity sysWechatUser;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    @JSONField(serialize = false)
    public String getPassword() {
        return null;
    }

    @Override
    public String getUsername() {
        return sysWechatUser.getOpenid();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

二、小程序用户实现类实现springsecurity中的UserDetailsService接口

package com.school.information.core.service;

import com.school.information.core.exception.ServiceException;
import com.school.information.core.security.entity.SecurityUser;
import com.school.information.entity.SysUserEntity;
import com.school.information.enums.result.SysResultEnum;
import com.school.information.enums.status.EnabledEnum;
import com.school.information.service.SysMenuService;
import com.school.information.service.SysRoleService;
import com.school.information.service.SysUserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Set;

@Service
@Slf4j
public class SecurityUserServiceImpl implements UserDetailsService {
    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysMenuService menuService;
    @Resource
    private SysRoleService roleService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("##进入后台用户登录逻辑代码处理:{}", username);
        // 根据登录名获取用户信息
        SysUserEntity sysUser = sysUserService.getByPhone(username);
        if (Objects.isNull(sysUser)) {
            log.error("##登录用户:{}不存在", username);
            throw new ServiceException(SysResultEnum.USER_NAME_NO_EXISTED);
        } else if (EnabledEnum.DISABLE.equals(sysUser.getIsEnabled())) {
            log.error("##登录用户:{}已停用", username);
            throw new ServiceException(SysResultEnum.USER_DISABLED);
        }
        // 获取用户角色、权限信息  用户角色和权限信息保留一个即可
        SecurityUser securityUser = new SecurityUser();
        securityUser.setSysUser(sysUser);

        Set<String> perms = menuService.findMenuByUserId(sysUser.getId());
        securityUser.setPermissions(perms);

        Set<String> roles = roleService.findRoleByUserId(sysUser.getId());
        securityUser.setRoles(roles);

        return securityUser;
    }
}

三、小程序自定义验证继承AbstractAuthenticationToken类

package com.school.information.core.security.authen;

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert;

import java.util.Collection;

/**
 * 微信小程序登录token验证,模仿 WechatAppAuthenticationToken 重写编写
 */
public class WechatAppAuthenticationToken extends AbstractAuthenticationToken {
    private static final long serialVersionUID = 580L;
    private final Object principal;
    private Object credentials;

    public WechatAppAuthenticationToken(Object principal, Object credentials) {
        super((Collection) null);
        this.principal = principal;
        this.credentials = credentials;
        this.setAuthenticated(false);
    }

    public WechatAppAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.principal = principal;
        this.credentials = credentials;
        super.setAuthenticated(true);
    }

    public static WechatAppAuthenticationToken unauthenticated(Object principal, Object credentials) {
        return new WechatAppAuthenticationToken(principal, credentials);
    }

    public static WechatAppAuthenticationToken authenticated(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
        return new WechatAppAuthenticationToken(principal, credentials, authorities);
    }

    public Object getCredentials() {
        return this.credentials;
    }

    public Object getPrincipal() {
        return this.principal;
    }

    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
        Assert.isTrue(!isAuthenticated, "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
        super.setAuthenticated(false);
    }

    public void eraseCredentials() {
        super.eraseCredentials();
        this.credentials = null;
    }
}

四、小程序自定义身份验证管理器实现springsecurity中的AuthenticationProvider

package com.school.information.core.security.provider;

import cn.hutool.core.util.ObjectUtil;
import com.school.information.core.security.authen.WechatAppAuthenticationToken;
import com.school.information.core.security.entity.WechatAppUser;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
 * 微信小程序登录验证, 模仿 DaoAuthenticationProvider
 */
public class WechatAppUserAuthenticationProvider implements AuthenticationProvider {

    private UserDetailsService userDetailsService;

    public WechatAppUserAuthenticationProvider() {

    }

    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 自定义小程序认证登录 根据小程序openid获取小程序用户信息
        WechatAppUser wechatAppUser = (WechatAppUser) userDetailsService.loadUserByUsername(authentication.getName());
        if (ObjectUtil.isEmpty(wechatAppUser)) {
            throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
        }
        // 注意要调用 authenticated() 方法 这个是认证通过了的
        WechatAppAuthenticationToken result = WechatAppAuthenticationToken.authenticated(wechatAppUser, authentication.getCredentials(), null);
        result.setDetails(authentication.getDetails());

        return result;
    }

    public boolean supports(Class<?> authentication) {
        return WechatAppAuthenticationToken.class.isAssignableFrom(authentication);
    }

    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    protected UserDetailsService getUserDetailsService() {
        return this.userDetailsService;
    }
}


http://lihuaxi.xjx100.cn/news/1829968.html

相关文章

vulnhub6

靶机地址&#xff1a;https://download.vulnhub.com/evilbox/EvilBox---One.ova 准备工作 可以先安装 kali 的字典: sudo apt install seclists ​ 或者直接输入 seclists​&#xff0c;系统会问你是否安装&#xff0c;输入 y 即可自动安装 733 x 3751414 x 723 ​ 默认路…

kafka常见命令汇总

停止命令 bin/zookeeper-server-stop.sh -daemon config/zookeeper.properties bin/kafka-server-stop.sh -daemon config/server.properties 启动命令 bin/zookeeper-server-start.sh -daemon config/zookeeper.properties bin/kafka-server-start.sh -daemon config/server.…

连接docker swarm和凌鲨

docker swarm相比k8s而言&#xff0c;部署和使用都要简单很多&#xff0c;比较适合中小研发团队。 通过连接docker swarm和凌鲨&#xff0c;可以让研发过程中的常用操作更加方便。 更新容器镜像调整部署规模查看日志运行命令 使用步骤 部署swarm proxy 你可以通过linksaas…

讲述 什么是鸿蒙 为什么需要鸿蒙 为什么要学习鸿蒙

首先 我们为什么要学习鸿蒙开发&#xff1f; 因为 鸿蒙发展前景巨大 鸿蒙自发布依赖 一直受社会各界关注 强两百的 App厂商 大部分接受了与鸿蒙的合作 硬件也有非常多与鸿蒙合作的厂商 鸿蒙的合作企业基本已经覆盖整个互联网客户的主流需求 所以鸿蒙的崛起不过是早晚的问题 …

小程序中的大道理--综述

前言 以下将用一个小程序来探讨一些大道理, 这些大道理包括可扩展性, 抽象与封装, 可维护性, 健壮性, 团队合作, 工具的利用, 可测试性, 自顶向下, 分而治之, 分层, 可读性, 模块化, 松耦合, MVC, 领域模型, 甚至对称性, 香农的信息论等等. 为什么不用大程序来说大道理呢? …

深度学习基于Python+TensorFlow+Django的水果识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介简介技术组合系统功能使用流程 二、功能三、系统四. 总结 一项目简介 # 深度学习基于PythonTensorFlowDjango的水果识别系统介绍 简介 该水果识别系统基于…

Tars-GO 开发

默认环境是安装好的 创建服务: tarsgo make App Server Servant GoModuleName Tars 实例的名称&#xff0c;有三个层级&#xff0c;分别是 App&#xff08;应用&#xff09;、Server&#xff08;服务&#xff09;、Servant&#xff08;服务者&#xff0c;有时也称 Object&am…

unordered_map 与 unordered_set 的模拟实现

unordered_map 与 unordred_set 的模拟实现与 map 与 set 的模拟实现差不多。map 与 set 的模拟实现中&#xff0c;底层的数据结构是红黑树。unordered_map 与 unordered_set 的底层数据结构是哈希表。因此&#xff0c;在模拟实现 unordered_map 与 unordred_set 之前你必须确保…