卖不甜枣 发表于 2022-6-24 02:20:18

零基础学习SpringSecurity OAuth2 四种授权模式(理论+实战)(配套视频讲解)

配套视频直达
背景

前段时间有同学私信我,让我讲下Oauth2授权模式,并且还强调是零基础的那种,我也不太理解这个零基础到底是什么程度,但是我觉得任何阶段的同学看完我这个视频,对OAuth2的理解将会有很大的提升,并且也会熟练的使用SpringSecurity OAuth2,轻松搭建认证服务和资源服务。
大概了解下 SpringSecurity

Spring Security是一套安全框架,可以基于RBAC(基于角色的权限控制)对用户的访问权限进行控制,核心思想是通过一套filterChanin进行拦截和过滤
再来了解OAuth2

Oauth2是一个关于授权的官方标准,核心思路是通过各种认证手段(需要用户自己选择实现)进行认证用户身份,并颁发token,使得第三方应用可以使用该令牌在限定时间和限定范围内访问指定资源
再来了解SpringSecurity Oauth2

Spring Security OAuth2建立在Spring Security的基础之上,实现了OAuth2的规范
概念部分铺垫完成了,现在我们讲下OAuth2的四种授权模式
四种授权模式

为什么提供四种呢?
四种授权模式代表OAuth授权第三方的不同互信程度
授权码模式(最安全,也最常用)

通过授权码获取token
场景

当用户使用B网站的账号(如微信)授权登陆A网站
步骤



[*]跳转到B网站授权页面,输入B网站用户名和密码
[*]B网站认证服务验证通过,回调网站A提供的回调地址,并带上认证code
[*]A网站收到回调之后,提取code,再调用B网站获取token的接口,并带上A网站在B网站上面注册的client_id和client_secert
别说话,看图

https://img-blog.csdnimg.cn/ebf5451f6a9945bca80c91fb0522805b.png
https://img-blog.csdnimg.cn/2bc57abd27b4433eb2c10a985cdac5c8.png
简化模式(有中间人攻击的风险)

简化模式在授权码模式的基础上减去了获取授权码的步骤,B网站认证通过之后,直接返回token 回调给A网站,所以又称为(授权码)“隐藏式”(implicit)
步骤



[*]跳转到B网站授权页面,输入B网站用户名和密码
[*]B网站认证服务验证通过,回调网站A提供的回调地址,并带上token信息
看图

https://img-blog.csdnimg.cn/53e62e6c1cc54205a8dca5c13d506781.png
密码模式(除非没得选才用,毕竟涉及到用户隐私)

A网站要求用户直接输入用户名和密码,A网站自己拿着用户的密码和账号去B网站进行认证,直接获取token
步骤



[*]A网站要求用户输入账号和密码
[*]A网站携带账号和密码去B网站认证
[*]B网站认证通过,直接返回token给A网站
看图

https://img-blog.csdnimg.cn/7c3b597554864b31afc02931b477186e.png
客户端模式

客户端模式其实和用户就没关系了,其实也可以说它不属于Oauth了,因为是用网站A自己的身份信息去B网站认证获取token,A网站上的所有用户去访问B网站的资源,都是用的A网站自己的客户端信息。
场景

这个一般用于微服务之间进行认证,如服务A想访问服务B,那么服务B需要校验服务A有没有权限访问自己,所以就需要校验服务B的token,这时就可以采用客户端模式,后面讲资源服务去认证中check_toekn的时候,用的就是这种方式。
看图

https://img-blog.csdnimg.cn/efcf59852f72496382e53ba744c9b09a.png
现在四种授权模式讲完了,大家是不是有个疑问:
前面三种授权方式,拿到token之后,是怎么和用户进行绑定的呢?
接下来看下实战过程中,是怎么用SpringSecurity Oauth2 实现四种授权方式。
准备好电脑,开干

创建认证服务

创建ClientDetailsServiceImpl

根据clientID获取客户端信息,security会去调用多次,所以一般加上缓存
package com.lglbc.oauth2.config.details.client;

import com.lglbc.oauth2.entity.OauthClient;
import com.lglbc.oauth2.enums.PasswordEncoderTypeEnum;
import com.lglbc.oauth2.service.OauthClientService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
* @author: 乐哥聊编程(全平台同号)
*/
@Service
@RequiredArgsConstructor
public class ClientDetailsServiceImpl implements ClientDetailsService {
    private final OauthClientService oauthClientService;

    @Override
    public ClientDetails loadClientByClientId(String clientId) {
      // 获取client信息
      OauthClient oauthClient = oauthClientService.lambdaQuery().eq(OauthClient::getClientId, clientId).one();
      if (Objects.nonNull(oauthClient)) {
            BaseClientDetails clientDetails = new BaseClientDetails(
                  oauthClient.getClientId(),
                  oauthClient.getResourceIds(),
                  oauthClient.getScope(),
                  oauthClient.getAuthorizedGrantTypes(),
                  oauthClient.getAuthorities(),
                  oauthClient.getWebServerRedirectUri());
            clientDetails.setClientSecret(PasswordEncoderTypeEnum.NOOP.getPrefix() + oauthClient.getClientSecret());
            clientDetails.setAccessTokenValiditySeconds(oauthClient.getAccessTokenValidity());
            clientDetails.setRefreshTokenValiditySeconds(oauthClient.getRefreshTokenValidity());
            return clientDetails;
      } else {
            throw new NoSuchClientException("没找到客户端信息");
      }
    }
} 创建自定义的userDetails(自定义用户自己的信息)

package com.lglbc.oauth2.config.details.user;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: 乐哥聊编程(全平台同号) */@Data@Builder@AllArgsConstructor@NoArgsConstructorpublic class SysUserDetails implements UserDetails {    /**   * 扩展字段   */    private Long userId;    /**   * 默认字段   */    private String username;    private String password;    private Boolean enabled;    private Collection authorities;    @Override    public Collection
页: [1]
查看完整版本: 零基础学习SpringSecurity OAuth2 四种授权模式(理论+实战)(配套视频讲解)