SpringCloud微服务整合Spring Security进行统一鉴权

这篇具有很好参考价值的文章主要介绍了SpringCloud微服务整合Spring Security进行统一鉴权。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、思想

  • 网关gateway
  • 普通资源微服务member
  • 鉴权微服务auth
    为了做到更灵活的方法级别的鉴权操作,决定将权限控制下放到具体的普通微服务,其实并不需要多配置很多东西。网关只负责转发请求,鉴权则是由auth认证微服务来完成的。
  • 网上很多都是在网关层面进行鉴权,但是这么做不灵活,并不能做到方法级别的鉴权。比如,普通资源微服务中的一些方法并不需要权限,是开放访问的,而有些方法是需要鉴权的。网关层面只能决定某个微服务是否需要鉴权,要么所有方法全做,要么全不做,是缺少灵活度的。

2、步骤

2.1、前言

  • 有一个大坑,记得如果是单机操作多个微服务项目,要给每个微服务添加session cookie name,如下
server:
  port: 8003
  servlet:
    session:
      cookie:
        #防止Cookie冲突,冲突会导致登录验证不通过
        name: OAUTH2-CLIENT-SESSIONID03
  • 一定一定要做这一步。

2.2、关系

  • 网关gateway
  • 普通资源微服务member
  • 鉴权微服务auth

2.3、认证微服务auth

  • 不需要变动,参考我之前系列的博客:https://blog.csdn.net/qq_41076797/article/details/129985272

2.3.1、微服务目录

springcloud集成security,微服务,spring cloud,springsecurity
其中整合了swagger的两个配置文件和本项目无关,可忽略

2.3.2、引入必要依赖

auth端:

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

还有一些必要的组件是放到了common模块,然后在auth端引入common模块就好了。比如有nacos,一些实体类等等。要记得引入common后也要做必要的配置,比如nacos,相关配置可见博客:https://blog.csdn.net/qq_41076797/article/details/128509393、https://blog.csdn.net/qq_41076797/article/details/128508723;这里就不详细说了。

2.3.3、配置用户鉴权实体类LoginUser

  • 用户已经有实体类User了,这里要对它进行封装,从鉴权的角度把User包一层。
  • 这里要实现UserDetails接口,实现其中的必要方法,这也属于固定套路,这样才能用于权限鉴定。
  • 在auth微服务下面开个detail文件夹,创建实体类LoginUser,
package com.lyy.yingwudemo.yingwu_auth.service;

/**
 * @author :lyy
 * @date : 04-06-10:15
 */
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

/**
 * 登录用户身份权限
 *
 * @author ruoyi
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LoginUser implements UserDetails
{
   
    private static final long serialVersionUID = 1L;

    /**
     * 扩展字段
     */
    private Long userId;

    /**
     * 默认字段
     */
    private String username;
    private String password;
    private Boolean enabled;
    private Collection<SimpleGrantedAuthority> authorities;


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

    @Override
    public String getPassword() {
   
        return this.password;
    }

    @Override
    public String getUsername() {
   
        return this.username;
    }

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

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

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

    @Override
    public boolean isEnabled() {
   
        return this.enabled;
    }
}

2.3.4、创建根据用户名获取封装的用户信息的service:UserDetailServiceImpl

  • 这个主要就是定义一个类实现固定的接口UserDetailsService中的固定的方法loadUserByUsername,这个方法就是根据字符串username返回一个UserDetails,因为得让springsecurity直到你要进行鉴权的对象啥样啊!
  • 这里通过feign从用户服务member获取用户信息。
package com.lyy.yingwudemo.yingwu_auth.service;

import com.alibaba.fastjson.TypeReference;
import com.lyy.yingwuDemo.yingwu_common.entity.User;
import com.lyy.yingwuDemo.yingwu_common.utils.R;
import com.lyy.yingwudemo.yingwu_auth.feign.MemberFeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author :lyy
 * @date : 04-06-13:21
 */
@Service
@Slf4j
public class UserDetailServiceImpl implements UserDetailsService {
   

    @Autowired
    private MemberFeignService memberFeignService;

    /**
     *
     * @param username
     * @return 就是负责构建一个UserDetails,咱们之前构建的实体类LoginUser就实现了UserDetails,所以是符合要求的
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
   
        // 后面从管理端获取用户信息
        R r = memberFeignService.getMemberUsername(username);
        TypeReference<User> typeReference = new TypeReference<User>() {
   };
        User user=r.getData("user",typeReference);
        if(user==null)
            throw new UsernameNotFoundException("用户不存在");
        LoginUser userDetails = loadUser(user);
        if (!userDetails.isEnabled()) {
   
            throw new DisabledException("该账户已被禁用!");
        } else if (!userDetails.isAccountNonLocked()) {
   
            throw new LockedException("该账号已被锁定!");
        } else if (!userDetails.isAccountNonExpired()) {
   
            throw new AccountExpiredException("该账号已过期!");
        }
        return userDetails;
    }

    private LoginUser loadUser(User user) {
   
        Collection<SimpleGrantedAuthority> authorities =new ArrayList<>();
        user.getUserTags().stream().forEach(tag->
            authorities.add(new SimpleGrantedAuthority(tag.equals("1")?"ROLE_ADMIN":"ROLE_USER"))
        );

        LoginUser loginUser = new LoginUser();
        loginUser.setAuthorities(authorities);

        return LoginUser.builder()
                .userId(1L)
                .username(user.getUserName())
                .enabled(user.getEnable())
                .authorities(authorities)
                // 这里的密码就是正确密码,要拿前端传来的和下面的比较
                .password(new BCryptPasswordEncoder().encode(user.getPassWord())).build();
    }
}

2.3.5、如果不想自己设计用户service

不管要不要自己手动设计service,都要通过rpc调用,查询到username对应的那个用户,以及对应的权限
参考以下代码文章来源地址https://www.toymoban.com/news/detail-764046.html

@Service
@Slf4j
public class SecurityUserDetailService implements UserDetailsService {
   


    @Autowired
    private UserService userService;

    @Autowired
    private PermissionService permissionService;


    @Override
    public UserDetails loadUserByUsername(String username) {
   

        UserEntity user = userService.getUserByUsername(username);
        if (user == null) {
   
            return null;
        }
        //获取权限
        List<PermissionEntry> permissions = permissionService.getPermissionsByUserId(user.getId());
        List<String> codes = permissions.stream().map(PermissionEntry::getCode).collect(Collectors

到了这里,关于SpringCloud微服务整合Spring Security进行统一鉴权的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Springcloud gateway网关+认证服务+token方式,入口层认证统一微服务鉴权【设计实践】

    目录 背景 实现 gateway maven配置 yml配置 页面登录拦截配置类 白名单配置 token工具类 登录配置类 全局过滤器类 项目启动类 分布式项目的单点登录分为认证服务(单点登录服务端)和业务服务(单点登录客户端)两个角色, 当访问业务服务时,认证服务客户端SDK校验一下是否

    2024年02月15日
    浏览(30)
  • SpringCloud整合spring security+ oauth2+Redis实现认证授权

    在微服务构建中,我们一般用一个父工程来通知管理依赖的各种版本号信息。父工程pom文件如下: 在SpringCloud微服务体系中服务注册中心是一个必要的存在,通过注册中心提供服务的注册和发现。具体细节可以查看我之前的博客,这里不再赘述。我们开始构建一个eureka注册中

    2024年02月06日
    浏览(41)
  • Spring Security 6.x 系列【45】微服务篇之搭建统一认证服务

    有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.0.4 本系列Spring Security 版本 6.0.2 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo

    2024年02月09日
    浏览(32)
  • 【高危】Spring Security鉴权规则错误配置风险

    Spring Security 是一套为基于Spring的应用程序提供说明性安全保护的安全框架。 在 Spring Security 受影响的版本中,由于 Spring Security 的授权规则会应用于整个应用程序上下文,当应用程序中包含多个servlet,并且其中一个为DispatcherServlet时 ,使用 requestMatchers(String) 方法错误地将非

    2024年02月15日
    浏览(20)
  • 【springcloud 微服务】Spring Cloud Alibaba整合Sentinel详解

    目录 一、前言 二、环境准备 2.1 部署sentinel管控台 2.1.1 官网下载sentinel的jar包 2.1.2 启动控制台

    2023年04月09日
    浏览(35)
  • 【Spring Security】分布式鉴权的使用

    🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《Spring Security》。🎯🎯 👉点击这里,就可以查看我的主页啦!👇👇 Java方文山的个人主页 🎁如果感觉还不错的话请给我点赞吧!🎁🎁 💖期待你的加入,一

    2024年02月02日
    浏览(29)
  • Java之SpringCloud Alibaba【五】【微服务 Sentinel整合openfeign进行降级】

    Java之SpringCloud Alibaba【一】【Nacos一篇文章精通系列】 跳转 Java之SpringCloud Alibaba【二】【微服务调用组件Feign】 跳转 Java之SpringCloud Alibaba【三】【微服务Nacos-config配置中心】 跳转 Java之SpringCloud Alibaba【四】【微服务 Sentinel服务熔断】 跳转 Java之SpringCloud Alibaba【五】【微服务

    2024年02月11日
    浏览(31)
  • 【springcloud微服务】Spring Cloud Alibaba 整合dubbo与openfeign

    dubbo与springcloud都可以单独作为微服务治理框架在生产中进行使用,但使用过springcloud的同学大概了解到,springcloud生态的相关组件这些年已经逐步停更,这就导致在服务架构演进过程中的迭代断层,以至于一些新的技术组件引入困难重重,于是在国内的市场上就有了升级版的

    2024年02月07日
    浏览(36)
  • Spring Gateway + Oauth2 + Jwt网关统一鉴权

    之前文章里说过,分布式系统的鉴权有两种方式,一是在网关进行统一的鉴权操作,二是在各个微服务里单独鉴权。 第二种方式比较常见,代码网上也是很多。今天主要是说第一种方式。 重要前提:需要收集各个接口的uri路径和所需权限列表的对应关系,并存入缓存。 服务

    2024年02月03日
    浏览(33)
  • Spring Cloud Gateway + Oauth2 实现统一认证和鉴权!

    micro-oauth2-gateway:网关服务,负责请求转发和鉴权功能,整合Spring Security+Oauth2; micro-oauth2-auth:Oauth2认证服务,负责对登录用户进行认证,整合Spring Security+Oauth2; micro-oauth2-api:受保护的API服务,用户鉴权通过后可以访问该服务,不整合Spring Security+Oauth2。 我们首先来搭建认

    2024年01月16日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包