0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是oauth协议

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-10-08 11:39 次阅读

本篇文章让我带你认识一下什么是oauth协议

什么是 oauth协议 ?

百度百科上解释:允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。

简单的来讲就是一个令牌,这个令牌可以有一定的权限,在不知道用户密码的情况下也可以进行部分的功功能操作。用一个例子帮助理解:一个甲方公司,公司里面使用一卡通,这张卡可以门禁,食堂,等等,公司招了外包进来,外包只能开通门禁就行,其他的权限是没有的。这时候公司就不会给一张正式员工的卡,而是外包的卡,正编员工卡就是用户的账号密码,这个外包卡就相当于是一个令牌,并且可能公司会给你的外包卡设置一个有效期,等有效期快到的时候有需要申请延期。这个就相当于是oauth协议模式。用户不会给你用户名和密码,那样相当于放开了所有的权限,而会给你提供一个令牌,在有效期类可以访问特定的功能服务 使用令牌的优点:

  • 令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
  • 令牌可以被数据所有者撤销,会立即失效。
  • 令牌有权限范围(scope),对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限

oauth协议有四种模式;

1、授权码模式 2、隐藏式 3、密码式 4、客户端凭证 其中授权码方式是最常用的流程,安全性也最高,今天我们就来着重讲一下授权码模式。 授权码模式: 指的是第三方应用先申请一个授权码,然后再用该码获取令牌,授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

授权码模式主要分为几个步骤

以甲方公司员工卡系统(SelfResearch.com)和外包公司员工卡系统(outsource.com)为例,下面是授权码模式的流程图片

请求授权码

首先,甲方公司给外包员工方提供一个授权链接,外包员工点击连接,申请授权码,连接参数如下所示

https://SelfResearch.com/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

response_type参数表示要求返回授权码(code), client_id参数让 甲方 知道是谁在请求, redirect_uri参数是 甲方系统 接受或拒绝请求后的跳转网址, scope参数表示要求的授权范围(这里是只读)。

返回授权码

用户跳转到这个之后,甲方公司会先要求用户登录,然后请求授权,如果同意就跳转到redirect_uri这个参数的地址,并返回授权码

https://SelfResearch.com/callback?code=AUTHORIZATION_CODE

code就是表示授权码

请求令牌

外包员工拿着授权码去请求令牌

https://SelfResearch.com/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

  • client_id参数和client_secret参数用来让 甲方公司 确认 外包员工 的身份(client_secret参数是保密的,因此只能在后端发请求)。
  • grant_type参数的值是AUTHORIZATION_CODE,表示采用的授权方式是授权码。
  • code参数是上一步拿到的授权码。
  • redirect_uri参数是令牌颁发后的回调网址。

返回令牌 外包员工访问redirect_uri会得到一串json数据:

{
    "access_token": "67c4051b-36c8-11ec-af33-00163e0808bf",
    "token_type": "bearer",
    "refresh_token": "71975ccc-36c8-11ec-af33-cfd2826915e5",
    "expires_in": 3249,
    "scope": "read"

access_token就是令牌了,用户需要访问其他接口就需要带上这个token去访问了 refresh_token这个是刷新令牌,如果需要使用新的token,就需要通过这个刷新令牌来获取最新的access_token。

实现 oauth2,可以分为三个步骤

  • 认证服务
  • 资源服务
  • 第三方服务

现在第三方用户(test9527)想去访问资源中的部分功能(接口),但是改功能只有User角色才能访问,需要先通过认证服务器获取user的授权码,然后拿着这个code和自己账号信息去获取token,并校验通过之后才能访问到资源服务器,也就是第三方用户通过 test9527 可以访问本来需要user权限才能访问的资源功能(接口)

实现步骤:

创建三个服务oauth-server(认证服务)、resource-server(资源服务)、third-server(第三方服务

图片

maven依赖

< !--    oauth2    -- >
< dependency >
    < groupId >org.springframework.security.oauth< /groupId >
    < artifactId >spring-security-oauth2< /artifactId >
    < version >2.1.3.RELEASE< /version >
< /dependency >
< !--    spring security-- >
< dependency >
    < groupId >org.springframework.boot< /groupId >
    < artifactId >spring-boot-starter-security< /artifactId >
< /dependency >

oauth-server 服务配置文件

/**
 * 模拟第三方授权配置
 */
@EnableAuthorizationServer
@Configuration
public class AuthConfig extends AuthorizationServerConfigurerAdapter {

    @Resource
    ClientDetailsService clientDetailsService;

    /**
     * 资源服务器校验Token
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.checkTokenAccess("permitAll()").allowFormAuthenticationForClients();
    }
    /**
     * 第三方客户端请求配置,和资源服务访问的配置,不设置默认都可以访问,提供默认回调地址
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //第三方用户
                .withClient("test9527")
                .secret(new BCryptPasswordEncoder().encode("test9527"))
                .resourceIds("resource")
                //认证模式
                .authorizedGrantTypes("authorization_code","refresh_token")
                .scopes("all")
                //回调地址
                .redirectUris("http://localhost:8082/notify.html");
    }
    /**
     * 配置访问端点
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authorizationCodeServices(authorizationCodeServices()).tokenServices(tokenServices());
    }
    /**
     * 内存管理
     */
    @Bean
    AuthorizationCodeServices authorizationCodeServices() {
        return new InMemoryAuthorizationCodeServices();
    }
    /**
     * Token管理规则
     */
    @Bean
    AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices services = new DefaultTokenServices();
        services.setClientDetailsService(clientDetailsService);
        services.setSupportRefreshToken(true);
        services.setTokenStore(tokenStore());
        services.setAccessTokenValiditySeconds(3600);
        services.setRefreshTokenValiditySeconds(3600*7);
        return services;
    }
    @Bean
    TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

配置spring security

/**
 * 模拟本地用户配置
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 密码加密方式
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    /**
     * 内存中虚拟用户和角色
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password(new BCryptPasswordEncoder().encode("123456"))
                .roles("user");
    }
    /**
     * 表单登录
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().formLogin();
    }
}

resource-server配置

/**
 * 资源服务管理配置
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    /**
     * Token令牌校验
     */
    @Bean
    RemoteTokenServices tokenServices() {
        RemoteTokenServices services = new RemoteTokenServices();
        services.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");
        services.setClientId("test9527");
        services.setClientSecret("test9527");
        return services;
    }
    /**
     * 服务资源ID配置
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("resource").tokenServices(tokenServices());
    }
    /**
     * 模拟用户权限规则
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                           //访问user下的路径需要user角色
                .antMatchers("/user/**").hasRole("user")
                .anyRequest().authenticated();
    }

resource下的功能(接口)

图片

第三方服务首先认证,获取授权码code http://localhost:8080/oauth/authorize?client_id=test9527&response_type=code&scope=all&redirect_uri=http://localhost:8082/notify.html

此时会到认证服务器中的user认证

图片

此时需要user用户同意授权,当认证服务中的user用户同意之后,到如下页面,此时看接口可以知道已经拿到code授权码,并跳转到我们需要跳转的地址

redirect_uri=http://localhost:8082/notify.html

图片

拿到授权码之后访问回调地址 http://localhost:8082/notify.html?code=Rs067L 然后通过code,client_id,client_secret 等参数访问获取令牌地址 https://SelfResearch.com/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=SMD5nj&redirect_uri=redirect_uri=http://localhost:8082/notify.html 成功之后会返回token,刷新token,以及token有效时间,如下图片

拿到token之后,我们再去访问资源服务器,此时就能顺利访问到功能(接口)了

图片

最终效果,最终第三方用户test9527访问当了资源服务器功

图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    6512

    浏览量

    87601
  • 参数
    +关注

    关注

    11

    文章

    1398

    浏览量

    31472
收藏 人收藏

    评论

    相关推荐

    #硬声创作季 06-JAVAEE实战项目课程—OAUTH2认证-OAuth2协议流程

    JAVA编程语言
    Mr_haohao
    发布于 :2022年09月04日 21:13:42

    跟着小狂玩天猫精灵智能设备对接--服务器篇(二)

    的一段,就是OAuth2.0第三方授权服务器的搭建,然后再来个小菜MySQL数据库的安装,这两个东西一旦完成,那么就剩协议对接了,在这片文章中我们把服务器搭建完成,然后下一篇讲具体的协议怎么对接最后一篇讲
    发表于 12-12 13:33

    K8s 从懵圈到熟练 – 镜像拉取这件小事

    应用都会遇到的一个一般性场景。私有镜像拉取其实也是这个场景。这里的镜像仓库,就跟网盘一样,是资源服务器,而容器集群则是三方服务,它需要访问镜像仓库获取镜像。理解 OAuth 2.0 协议OAuth
    发表于 10-14 15:38

    协议是什么 协议栈又是什么

    协议定义的是一系列的通信标准, 通信双方需要共同按照这一标准进行正常的数据收发;信的双方需要共同按照这一个标准进行正常的数据收发;(两人,说共同的语言,不然不能交流,一个听不懂外语的和说外语的交流
    发表于 08-05 07:00

    如何使用ESP8266作为简单页面的网络服务器来生成OAuth代码以批准设备并生成刷新令牌和访问令牌?

    寻找一些帮助来实现这个项目的一个版本。我使用 ESP8266 作为简单页面的网络服务器来生成 OAuth 代码以批准设备并生成刷新令牌和访问令牌。 一切正常,直到我到达与谷歌服务器的实际连接点。我
    发表于 05-19 12:41

    OSPF协议,OSPF协议是什么意思

    OSPF协议,OSPF协议是什么意思 OSPF协议  OSPF(Open Shortest Path First)是一个内部网关协议(Interior Gateway Protoco
    发表于 03-29 17:27 4564次阅读

    UDP协议,UDP协议是什么意思

    UDP协议,UDP协议是什么意思 UDP 是User Datagram Protocol的简称, 中文名是用户数据包协议,是 OSI 参考模型中一种无连接的传输层协议
    发表于 03-29 17:35 1408次阅读

    IP层协议,IP层协议的内容有哪些?

    IP层协议,IP层协议的内容有哪些? Internet上使用的一个关键的底层协议是网际协议,通常称IP协议。我们利用一个共同遵守的通信
    发表于 04-06 16:45 9480次阅读

    SIP协议,什么是SIP协议

    SIP协议,什么是SIP协议 SIP协议是NGN中的重要协议,越来越得到业界的重视。 一、SIP协议的背景和功能 SIP( 会话初
    发表于 04-07 16:12 2127次阅读

    V-CHARGE的V2I通讯系统由德国TU Braunschweig大学完成设计

    V-CHARGE为解决第一个问题选用了OAuth 2.0通讯协议OAuth2.0是OAuth协议的延续版本,但不向后兼容
    的头像 发表于 07-31 16:23 4679次阅读
    V-CHARGE的V2I通讯系统由德国TU Braunschweig大学完成设计

    OAuth2-Server OAuth 2.0授权服务器的实现

    ./oschina_soft/oauth2-server.zip
    发表于 06-30 09:19 0次下载
    <b class='flag-5'>OAuth</b>2-Server <b class='flag-5'>OAuth</b> 2.0授权服务器的实现

    六款开源项目推荐

    现在大部分的网络应用,登录、注册、密码加密保存、token 管理等功能都是必要的。为了让用户的隐私更能得到保障,使用起来更方便,OAuth 协议和单点登录系统也就应运而生。今天推荐的六款开源项目就是针对开发者的此类需求,通过学习开源项目,来让自己的技术更精进。
    的头像 发表于 07-12 15:15 2609次阅读

    SSO单点登录和OAuth2.0的区别和理解

    两者有很多相似之处,下面我们来解释一下这个过程。先来讲解SSO,通过SSO对比OAuth2.0,才比较好理解OAuth2.0的原理。SSO的实现有很多框架,比如CAS框架,以下是CAS框架的官方流程图。特别注意:SSO是一种思想,而CAS只是实现这种思想的一种框架而已
    的头像 发表于 11-07 11:41 505次阅读

    什么是单点登录?解读单点登录两个协议:SAML、OAuth2

    解单点登录 (SSO) 和 SSO 广泛使用的两种协议,即 SAML 和OAuth2。这是任何程序员都需要理解的复杂领域之一。 什么是单点登录? 单点登录 (SSO) 是用户可以使用一组凭据
    的头像 发表于 11-14 14:44 2385次阅读

    Spring Boot 3.1 中如何整合Spring Security和Keycloak

    虽然Keycloak 团队宣布了不再对Spring Security提供适配,但Spring Security长期以来一直为OAuth和OIDC提供强大的内置支持。所以,只要我们理解Spring Security是如何处理OAuth和OIDC的,那么与Keyloak的集成
    的头像 发表于 06-08 14:54 722次阅读
    Spring Boot 3.1 中如何整合Spring Security和Keycloak