认证授权SpringSecurity

news2024/10/5 13:00:45

如何引入SpringSecurity作为项目的权限认证服务

1.引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

2.配置4个类
内容资源

3.简单测试

@Slf4j
@RestController
public class LoginController {

    @Autowired
    XcUserMapper userMapper;


    @RequestMapping("/login-success")
    public String loginSuccess() {

        return "登录成功";
    }


    @RequestMapping("/user/{id}")
    public XcUser getuser(@PathVariable("id") String id) {
        XcUser xcUser = userMapper.selectById(id);
        return xcUser;
    }
    }

什么是OAuth2?

OAuth2是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。
1它为用户资源的授权提供了一个安全的、开放而又建议的标准。OAuth2的作用是为了解决访问资源的安全性以及灵活性。
2.它定义了通过access token去获取请求资源的机制,但是没有定义提供用户身份信息的标准方法。
3.OAuth2可以用来实现 secure delegated access,基于HTTPS,以及APIs,Service应用使用 access token 来进行身份验证

OAuth2的模式有四种,分别是授权码模式、简化模式、密码模式和客户端模式。最常用的就是授权码模式和密码模式
授权码模式典型例子就是微信扫码认证,自己可以点进链接详细了解具体实现。

在SpringSecurity中统一认证入口,如何做到统一的?

(就像你登录游戏可以有多种登录方式,如扫码登录,账号密码登录)
1.新建一个对象类,不管什么类型的登录前端传入的参数必须一致
2.新建一个实现UserDetailsService 的实现类,重写loadUserByUsername方法,该方法就是整个程序的统一入口,一旦点击登录就会先调用该方法,可以在该方法里编写逻辑
在这里插入图片描述

/**
 * @author Mr.M
 * @version 1.0
 * @description 认证用户请求参数
 * @date 2022/9/29 10:56
 */
@Data
public class AuthParamsDto {

    private String username; //用户名
    private String password; //域  用于扩展
    private String cellphone;//手机号
    private String checkcode;//验证码
    private String checkcodekey;//验证码key
    private String authType; // 认证的类型   password:用户名密码模式类型    sms:短信模式类型
    private Map<String, Object> payload = new HashMap<>();//附加数据,作为扩展,不同认证类型可拥有不同的附加数据。如认证类型为短信时包含smsKey : sms:3d21042d054548b08477142bbca95cfa; 所有情况下都包含clientId


}
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.ucenter.mapper.XcUserMapper;
import com.xuecheng.ucenter.model.dto.AuthParamsDto;
import com.xuecheng.ucenter.model.dto.XcUserExt;
import com.xuecheng.ucenter.model.po.XcUser;
import com.xuecheng.ucenter.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.userdetails.User;
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.Component;

import java.util.List;

//统一认证入口,账号密码、微信扫码登录
@Slf4j
@Component
public class UserServiceImpl implements UserDetailsService {
    @Autowired
    XcUserMapper xcUserMapper;

    @Autowired
    ApplicationContext applicationContext;

//    以后传入的对象就是AuthParamsDto,根据参数的不同来识别用户的登录类型
    
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //1.统一的请求参数,获取并转成实体类
        AuthParamsDto authParamsDto =null;
        try {
             authParamsDto = JSON.parseObject(s, AuthParamsDto.class);
        } catch (Exception e) {
            throw new RuntimeException("请求认证不符合参数要求");
        }
        //2.wx,password,third,根据不同的登录类型走不同的实现类
        String authType = authParamsDto.getAuthType();
        //3.不同的登录方法对数据库操作的逻辑不一样,如微信扫码(获取第三方access token就可以获取信息保存到数据库)和账号密码登录(验证账号密码的正确性,然后查库获取信息)验证的逻辑不一样
        String beanName=authType+"_authService";
        AuthService authService = applicationContext.getBean(beanName, AuthService.class);
        XcUserExt xcUserExt = authService.execute(authParamsDto);
        
        //4.根据类型执行验证逻辑,给前端封装令牌
        UserDetails userDetails = getUserPrincipal(xcUserExt);

        return userDetails;
    }

    private UserDetails getUserPrincipal(XcUserExt xcUser) {
        String password = xcUser.getPassword();
        xcUser.setPassword(null);
        //把用户信息转成json放入令牌中,方便其它服务拿到
        String userJson = JSON.toJSONString(xcUser);
        // 根据用户id查询全息
        String [] authorities={"test"};
        List<String> list=xcUserMapper.selectAuthoritiesByUserId(xcUser.getId());
        if (list.size()>0){
            authorities= list.toArray(new String[list.size()]);
        }
        //权限
        UserDetails userDetails = User.withUsername(userJson).password(password).authorities(authorities).build();
        return userDetails;
    }
}

对于第三步,设计就是一个接口不同的实现类根据@Service(“xxx_authService”)的值走不同的逻辑
账号密码登录逻辑

package com.xuecheng.ucenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.ucenter.feignclient.CheckCodeClient;
import com.xuecheng.ucenter.mapper.XcUserMapper;
import com.xuecheng.ucenter.model.dto.AuthParamsDto;
import com.xuecheng.ucenter.model.dto.XcUserExt;
import com.xuecheng.ucenter.model.po.XcUser;
import com.xuecheng.ucenter.service.AuthService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

//账号密码登录
@Service("password_authService")
public class PasswordAuthServiceImpl implements AuthService {
    @Autowired
    XcUserMapper xcUserMapper;

    //框架自带
    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    CheckCodeClient checkCodeClient;
    @Override
    public XcUserExt execute(AuthParamsDto authParamsDto) {
        //账号
        String username = authParamsDto.getUsername();
        //验证码 todo
        //前端输入的验证码
        String checkcode = authParamsDto.getCheckcode();
        //验证码存储的key
        String checkcodekey = authParamsDto.getCheckcodekey();
        if (StringUtils.isEmpty(checkcode)||StringUtils.isEmpty(checkcodekey)){
            throw new RuntimeException("请输入验证码");
        }

        Boolean verify = checkCodeClient.verify(checkcodekey, checkcode);
        if (verify==null||!verify){
            throw new RuntimeException("验证码输入错误");
        }

        //1.s就是username,根据username查询数据库,查询用户是否存在
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username));
        //2.查询为空报错
        if (xcUser==null){
            throw new RuntimeException("账号不存在");
        }
        //3.数据库密码
        String password = xcUser.getPassword();
        //校验
        String inputPassword = authParamsDto.getPassword();
        boolean matches = passwordEncoder.matches(inputPassword, password);
        if (!matches){
            throw new RuntimeException("账号或密码错误");
        }
        XcUserExt xcUserExt = new XcUserExt();
        BeanUtils.copyProperties(xcUser, xcUserExt);

        return xcUserExt;
    }
}

微信登录的逻辑(另一个实现类)

    @Override
    public XcUserExt execute(AuthParamsDto authParamsDto) {
        //得到账号
        String username = authParamsDto.getUsername();
        //查询数据库
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username));
        if(xcUser == null){
            throw new RuntimeException("用户不存在");
        }

        XcUserExt xcUserExt = new XcUserExt();
        BeanUtils.copyProperties(xcUser, xcUserExt);

        return xcUserExt;
    }

如何根据SpringSecurity框架自带的功能提供资源权限验证?

如普通员工不能调用查看员工工资,经理却可以。
1.准备条件,引入了SpringSecurity并且要进行权限控制的接口的服务配置了SpringSecurity的配置
数据表
在这里插入图片描述

2.在controller类中使用
@PreAuthorize(“hasAnyAuthority(‘xc_teachmanager_course_list’)”)//指定权限标识符
只要当它携带的令牌中有该权限才能访问
在已经有了SpringSecurity微服务的前提下,其它微服务的接口想进行权限限制,需要在这些微服务中集成OAuth2。这样,当用户访问这些微服务时,就可以通过OAuth2进行身份验证和授权。
引入配置

package com.xuecheng.content.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import java.util.Arrays;

/**
 * @author Administrator
 * @version 1.0
 **/
@Configuration
public class TokenConfig {

    String SIGNING_KEY = "mq123";


//    @Bean
//    public TokenStore tokenStore() {
//        //使用内存存储令牌(普通令牌)
//        return new InMemoryTokenStore();
//    }

    @Autowired
    private JwtAccessTokenConverter accessTokenConverter;

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(SIGNING_KEY);
        return converter;
    }


}

注意:权限在UserDetailsService的实现类中设置这个是在SpringSecurity的服务中,其它微服务不需要要修改,这里只是注明
在这里插入图片描述

也是在数据库中查询该用户的权限

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/426279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

客快物流大数据项目(一百一十三):注册中心 Spring Cloud Eureka

文章目录 注册中心 Spring Cloud Eureka 一、Eureka 简介 二、架构图

不得不了解的linux网络配置

目录一、查看及测试网络1.1查看网络配置1.1.1ifconfig命令—查看网络接口地址1.1.2route命令—查看路由条目1.1.3hostname命令—查看主机名称1.1.4netstat命令—查看网络连接情况1.1.5 ss命令/lsof 命令— 获取socket(套接字)统计信息1.2测试网络连接1.2.1ping命令—测试网络连…

1 Nginx跨域配置

跨域问题在之前的单体架构开发中&#xff0c;其实是比较少见的问题&#xff0c;除非是需要接入第三方SDK时&#xff0c;才需要处理此问题。但随着现在前后端分离、分布式架构的流行&#xff0c;跨域问题也成为了每个Java开发必须要懂得解决的一个问题。 跨域问题产生的原因 产…

项目管理职业发展前景怎么样?

项目管理职业发展前景怎么样&#xff1f;我们可以从这三个问题出发—— 第一个问题&#xff1a;在中国「项目管理」的专业性的体现/认同度如何&#xff1f;缺少专业知识对未来工作选择的限制程度如何&#xff1f; 由于现在有不少跨专业从业者&#xff0c;他们通过自学考证等途…

计算广告(十二)

FFM模型 FFM&#xff08;Field-aware Factorization Machine&#xff0c;领域感知因子分解机&#xff09;是一种广泛应用于推荐系统和点击率预测&#xff08;CTR&#xff09;等任务的机器学习模型。 它是基于FM&#xff08;Factorization Machine&#xff0c;因子分解机&…

nuscenes instance 调研笔记

nuscenes instance 调研笔记&#xff1a; 前言 nuscenes这个自动驾驶数据集挺大&#xff0c;官方devkit还提供了各种操作用于提高科研人员的效率&#xff0c;但是吧&#xff0c;东西多了学起来就乱七八糟的&#xff0c;本文仅以提取每个instance关联的所有images为例子&#…

USRP具有MIMO系统如何同步

MIMO系统要求 时间和频率同步&#xff0c;并且每个通道必须满足下面两个要求&#xff1a; 1&#xff09;时钟必须同步对齐 2&#xff09;对DSP操作时间也要对齐&#xff0c;来自同一的时钟边缘 波束成形和测向要求 除了采样时间和采样时钟对准外&#xff0c;系统还必须在每个…

华为OD机试 - 相同数字组成图形的周长(Java JS Python)

题目描述 有一个6464的矩阵,每个元素的默认值为0,现在向里面填充数字,相同的数字组成一个实心图形,如下图所示是矩阵的局部(空白表示填充0): 数字1组成了蓝色边框的实心图形,数字2组成了红色边框的实心图形。 单元格的边长规定为1个单位。 请根据输入,计算每个非0值…

java 数组和字符串操作

目录一、前言二、数组操作1.charAt操作2.getBytes操作3.toCharArray操作4.String.valueOf5.substring&#xff0c;toUpperCase&#xff0c;toLowerCase&#xff0c;concat6.indexOf7.Arrays使用一、前言 本文章主要讲解数组的一些基本操作&#xff0c;让我们写代码更加方便&am…

1.docker-安装及使用

1.安装步骤 Install Docker Engine on CentOS 1. 确定CenOS7及以上版本 cat /etc/redhat-release2.卸载旧版本 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine3.yum安…

软件测试岗位求职避坑,今年毁约应届生的公司有这么多?….

不知不觉九月已至&#xff0c;“金三银四”招聘旺季也落入尾声&#xff0c;大学生也迎来毕业季&#xff01; 这个时候&#xff0c;应届生开始集体走向社会&#xff0c;而职场人也迎来了跳槽涨薪的好时机。 可现实的求职情况却是一片困境&#xff1a;从中小微到“大厂”&#…

ICPC SWERC 2020 K - Unique Activities(SAM记录子串第一次出现的位置 or SAM + hash)

两种做法的效率差异 做法一&#xff1a;SAM记录子串第一次结束位置 做法二&#xff1a;SAM hash 题意&#xff1a; 给定一个字符串&#xff0c;让你找到只出现过一次&#xff0c;且长度最短的子串并输出&#xff0c;如果有多个则输出最先出现的那个。 思路&#xff1a…

迷宫问题-DFS-BFS

迷宫问题迷宫问题简介BFS解决迷宫最短路径问题DFS记录迷宫路径DFS解决迷宫所有路径问题迷宫问题简介 &#x1f680;学习过算法程序设计的应该都学习过迷宫这个问题&#xff0c;迷宫问题主要设计的算法就是DFS-深度优先遍历和BFS-广度优先遍历。 &#x1f680;在一个二维数组中…

Jmeter和Testlink自动化测试框架研究与实施

摘 要 目前基于Jmeter的接口自动化测试框架&#xff0c;大多只实现脚本维护和自动调度&#xff0c;无法与Testlink进行互通&#xff0c;实现测试方案与自动化实施流程连接&#xff0c;本文基于Testlink、Jmeter、Jenkins实现&#xff1a;通过Testlink统一维护接口自动化测试用…

搭建es集群

单点es的缺点&#xff1a;1.存储数据有限&#xff1b;2.单点故障问题&#xff08;es出现故障则整个服务会直接宕机&#xff09; 解决存储数据有限&#xff1a;搭建多台es服务器实现集群 解决单点故障&#xff1a;在不同的es服务器中进行备份数据&#xff08;例&#xff1a;在…

车载测试需要有哪些知识需要学习的?

一、车载行业前景 其中的车载测试也随着国家对新能源、智能驾驶等领域的支持&#xff0c;而异常活跃&#xff0c;目前我国共有9000家自动驾驶相关企业&#xff0c;而今年从华为、中兴、大唐等通信领域的企业到以阿里、腾讯、小米等为代表的互联网企业&#xff0c;均已布局自动…

浅谈继承和发扬传统文化路径

中华民族五千年文明历史,造就了博大精深的中华传统文化。如何继承和发扬传统文化,是当代文化爱好者和工作者所关注的&#xff0c;实现这一使命,文化传承需要在以下路径上发力: 1. “微更新”路径。在传承的基础上进行融合拓展,实现内涵丰富和更新。 2. “强保护”路径。利用立…

空压机远程监控系统解决方案

一、项目背景 随着物联网各种技术快速发展,各物联网远程监测应用场景也应用而生&#xff0c;空压机是一种空气压缩和气体输送设备&#xff0c;广泛运用于矿山、机械、电子、医疗等各行业。空压机常规都是需要人在现场监测和维护,现在通过物联网技术,远程监控成为可能&#xff…

利用Msray-plus提升SEO工作效率和效果

随着互联网的不断发展和普及&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已经成为了网站推广和营销的重要手段之一。SEO的核心是通过优化网站的结构、内容和关键词等&#xff0c;提高网站在搜索引擎中的排名&#xff0c;从而吸引更多的访问量和潜在客户。然而&#xf…

多通道振弦传感器无线采集采集仪如何开始使用

多通道振弦传感器无线采集采集仪如何开始使用 开始使用 设备电源 VS208~432 可使用内置电池&#xff08;默认&#xff09;也可使用外部电池工作。 需要特别注意&#xff1a;严禁内置和外部电池&#xff08;电源&#xff09;同时使用&#xff0c;严重时会造成短路起火&#xff0…