前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JustAuth 扩展 Gitea OAuth2 授权登录

JustAuth 扩展 Gitea OAuth2 授权登录

作者头像
Lcry
发布于 2025-05-11 12:29:50
发布于 2025-05-11 12:29:50
12100
代码可运行
举报
文章被收录于专栏:Lcry个人博客Lcry个人博客
运行总次数:0
代码可运行

今天在做自己的一个自用项目,由于不想记忆太多账号密码,也不想设置一个简单的密码并不安全,为了防止了密码忘记了每次都找,自建了 Gitea 私服,就打算直接接入第三方授权登录,Java 已经有这方面比较全的开箱即用的整合第三方登录的开源组件,就是 JustAuth,直接引入组件简单配置就能完成Github、Gitee、支付宝、新浪微博、微信、Google、Facebook、Twitter、StackOverflow等国内外数大多数主流的第三方平台授权登录策略。

由于自己是要集成 Gitea 私服,现在最新版都还没有支持,不知道是基于什么考虑,官方仓库有 issues177 就有人提过,但是一直处于打开状态。所以今天直接按照官方把这块代码完善了。

OAuth2 协议介绍

做之前还是先大概了解一下 oauth2 授权协议,OAuth 2.0 协议是一种三方授权协议,目前大部分的第三方登录与授权都是基于该协议的标准或改进实现。网上一大把资源都能查到,我这里直接用 AI 翻译的大白话介绍一下:

Auth 2.0 是一种授权机制,简单来说,它能让你在不把自己账号密码告诉其他应用的情况下,允许该应用访问你在另一个服务中的某些信息或功能。

比如说,你想在某个健身应用里分享你的运动数据到微信朋友圈。如果你直接把微信账号密码给健身应用,那太不安全了,万一应用有漏洞或者被黑客攻击,你的微信账号就危险了。这时候 OAuth 2.0 就派上用场了,你点击健身应用的分享按钮后,会跳转到微信的授权页面,你可以选择授权健身应用访问你的哪些信息,比如运动步数等,然后健身应用就可以根据你授权的范围,把相应数据分享到朋友圈,而它并不知道你的微信账号密码,也无法获取你其他未授权的信息。这样既方便又安全,能让不同的应用之间安全地进行信息交互和功能授权。

JustAuth 扩展 Gitea OAuth2 授权登录
JustAuth 扩展 Gitea OAuth2 授权登录

假设整个流程开始之前,用户已经登录,那么整个授权流程如下:

  1. 客户端请求授权服务器
  2. 授权授权服务的授权端点重定向用户至授权交互页面,并询问用户是否授权
  3. 如果用户许可,则授权端点验证客户端的身份,并发放授权码给客户端
  4. 客户端拿到授权码之后,携带授权码请求授权服务器的令牌端点下发访问令牌
  5. 令牌端点验证客户端的身份和授权码,通过则下发访问令牌和刷新令牌(可选)
  6. 客户端拿到访问令牌后,携带访问令牌请求资源服务器上的受保护资源
  7. 资源服务器验证客户端身份和访问令牌,通过则响应受保护资源访问请求

整个流程中,客户端都无法接触到用户的登录凭证信息,客户端通过访问令牌请求受保护资源,用户可以通过对授权操作的控制来间接控制客户端对于受保护资源的访问权限范围和时效。

OAuth2.0定义的5种角色

  • 客户端(Client)

客户端是 OAuth 服务的接入方,其目的是请求用户存储在资源服务器上的受保护资源,客户端可以移动应用、网页应用,以及电视应用等等。

  • 用户代理(User Agent)

用户代理是用户参与互联网的工具,一般可以理解为浏览器。

  • 资源所有者(Resource Owner)

受保护资源所属的实体,比如资源的持有人等,下文的用户即资源所有者。

  • 授权服务器(Authorization Server)

授权服务器的主要职责是验证资源所有者的身份,并依据资源所有者的许可对第三方应用下发令牌。

  • 资源服务器(Resource Server)

托管资源的服务器,能够接收和响应持有令牌的资源访问请求,可以与授权服务器是同一台服务器,也可以分开。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

流程解析

  • (A) 用户打开客户端以后,客户端要求用户给予授权。
  • (B) 用户同意给予客户端授权。
  • (C) 客户端使用上一步获得的授权,向认证服务器申请令牌。
  • (D) 认证服务器客户端进行认证以后,确认无误,同意发放令牌
  • (E) 客户端使用令牌,向资源服务器申请获取资源。
  • (F) 资源服务器确认令牌无误,同意向客户端开放资源。

OAuth 2.0 的授权流程可以用一个生活场景来简单理解,比如你去餐厅吃饭需要寄存外套:

  1. 用户请求服务(Client 向 Resource Owner 请求授权)
    • 你到餐厅后想寄存外套,但存包处不归餐厅管,而是由第三方安保公司(如「安心寄存」)负责。
  2. 跳转授权中心(Redirect 到 Authorization Server)
    • 服务员给你一张「寄存授权单」,让你去安保公司柜台填信息。你拿着单子走到安保公司窗口。
  3. 用户身份验证(Resource Owner 登录)
    • 安保人员问你姓名和手机号,你提供后,他们验证确实是你本人(类似输入账号密码登录)。
  4. 选择授权范围(Consent)
    • 安保人员给你一份《寄存授权协议》,问你:
      • 只寄存外套(授权只读权限)
      • 外套 + 背包(授权读写权限)
      • 允许代取(授权离线访问)
    • 你勾选「只寄存外套」后签字。
  5. 获取授权码(Authorization Code)
    • 安保人员给你一张「临时寄存牌」(授权码),上面有编号但不包含你的个人信息。
  6. 换取访问令牌(Access Token)
    • 你把临时寄存牌交给餐厅服务员,服务员拿这牌子去安保公司后台,用他们的「商家 ID」和「秘钥」换真正的「存包柜钥匙」(访问令牌)。
  7. 访问资源(Access Resource Server)
    • 服务员用钥匙打开存包柜帮你存外套,整个过程你不用把身份证或家门钥匙交给餐厅,而且钥匙只能开指定柜子(对应授权范围)。
  8. 令牌有效期
    • 存包柜钥匙可能有时间限制(如 4 小时有效),过期后服务员得拿你的临时寄存牌重新换钥匙(刷新令牌机制)。

JustAuth 集成 Gitea 授权

参考官方文档自定义第三方平台的OAuth 只需要实现实现AuthSource接口以及自定义一个Request。

下面给出 Gitea 的实现类,Gitea 的授权断点可以再这里找到:https://docs.gitea.com/zh-cn/development/oauth2-provider

Authorization Endpoint

/login/oauth/authorize

Access Token Endpoint

/login/oauth/access_token

OpenID Connect UserInfo

/login/oauth/userinfo

JSON Web Key Set

/login/oauth/keys

Oauth2 一共有四种授权模式:1)授权码模式(Authorization Code Grant);2)隐式授权模式(Implicit Grant);3)资源所有者密码凭证模式(Resource Owner Password Credentials Grant);4)以及客户端凭证模式(Client Credentials Grant),目前 Gitea 仅支持Authorization Code Grant)标准。

AuthGiteaSource.class:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.request.AuthDefaultRequest;

/**
 * gitea Oauth2 默认接口说明
 * * https://www.51it.wang
 *
 * @author lcry
 */
public enum AuthGiteaSource implements AuthSource {

    /**
     * 自己搭建的 gitea 私服
     */
    GITEA {
        /**
         * 授权的api
         */
        @Override
        public String authorize() {
            return AuthGiteaRequest.SERVER_URL + "/login/oauth/authorize";
        }

        /**
         * 获取accessToken的api
         */
        @Override
        public String accessToken() {
            return AuthGiteaRequest.SERVER_URL + "/login/oauth/access_token";
        }

        /**
         * 获取用户信息的api
         */
        @Override
        public String userInfo() {
            return AuthGiteaRequest.SERVER_URL + "/login/oauth/userinfo";
        }

        /**
         * 平台对应的 AuthRequest 实现类,必须继承自 {@link AuthDefaultRequest}
         */
        @Override
        public Class<? extends AuthDefaultRequest> getTargetClass() {
            return AuthGiteaRequest.class;
        }

    }
}

AuthGiteaRequest.class:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cn.hutool.core.lang.Dict;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthDefaultRequest;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.json.utils.JsonUtils;

/**
 * Gitea授权登录请求实现
 * https://www.51it.wang
 * @author lcry
 */
@Slf4j
public class AuthGiteaRequest extends AuthDefaultRequest {

    public static final String SERVER_URL = SpringUtils.getProperty("justauth.type.gitea.server-url");

    /**
     * 设定归属域
     */
    public AuthGiteaRequest(AuthConfig config) {
        super(config, AuthGiteaSource.GITEA);
    }

    public AuthGiteaRequest(AuthConfig config, AuthStateCache authStateCache) {
        super(config, AuthGiteaSource.GITEA, authStateCache);
    }

    @Override
    public AuthToken getAccessToken(AuthCallback authCallback) {
        String body = doPostAuthorizationCode(authCallback.getCode());
        Dict object = JsonUtils.parseMap(body);
        // oauth/token 验证异常
        if (object.containsKey("error")) {
            throw new AuthException(object.getStr("error_description"));
        }
        // user 验证异常
        if (object.containsKey("message")) {
            throw new AuthException(object.getStr("message"));
        }
        return AuthToken.builder()
            .accessToken(object.getStr("access_token"))
            .refreshToken(object.getStr("refresh_token"))
            .idToken(object.getStr("id_token"))
            .tokenType(object.getStr("token_type"))
            .scope(object.getStr("scope"))
            .build();
    }

    @Override
    protected String doPostAuthorizationCode(String code) {
        HttpRequest request = HttpRequest.post(source.accessToken())
            .form("client_id", config.getClientId())
            .form("client_secret", config.getClientSecret())
            .form("grant_type", "authorization_code")
            .form("code", code)
            .form("redirect_uri", config.getRedirectUri());
        HttpResponse response = request.execute();
        return response.body();
    }

    @Override
    public AuthUser getUserInfo(AuthToken authToken) {
        String body = doGetUserInfo(authToken);
        Dict object = JsonUtils.parseMap(body);
        // oauth/token 验证异常
        if (object.containsKey("error")) {
            throw new AuthException(object.getStr("error_description"));
        }
        // user 验证异常
        if (object.containsKey("message")) {
            throw new AuthException(object.getStr("message"));
        }
        return AuthUser.builder()
            .uuid(object.getStr("sub"))
            .username(object.getStr("name"))
            .nickname(object.getStr("preferred_username"))
            .avatar(object.getStr("picture"))
            .email(object.getStr("email"))
            .token(authToken)
            .source(source.toString())
            .build();
    }

}

配置文件格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
justauth:
  type:
    gitea:
      server-url: https://demo.gitea.com
      client-id: b3c5*********8f13910
      client-secret: gto_5t*********wiyykoa
      redirect-uri: ${justauth.address}/social-callback?source=gitea

所有参数信息直接通过登录 Gitea 个人账号-用户设置-应用-创建新的 OAuth2 应用程序。

验证流程:

JustAuth 扩展 Gitea OAuth2 授权登录
JustAuth 扩展 Gitea OAuth2 授权登录
JustAuth 扩展 Gitea OAuth2 授权登录
JustAuth 扩展 Gitea OAuth2 授权登录
JustAuth 扩展 Gitea OAuth2 授权登录
JustAuth 扩展 Gitea OAuth2 授权登录

总结

通过本文你可以通过扩展 JustAuth 组件实现所有支持 Oauth2 授权登录,本文代码本来打算直接提交给 JustAuth,但是看了了仓库还有很多 pull request 作者没有合并,并且最近更新也是 5 个月前,可能作者是觉得已经开放了自定义扩展,可以自己内部扩展就行了,没必要都实现,所以就先这样吧。

参考链接

OAuth2.0 协议原理 OAuth流程 JustAuth-demo 示例仓库 justauth-spring-boot-starter 仓库

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
第三方登录
大家经常被注册登录繁琐的步骤击退,经常进几个不同的网站要输入几次用户密码,特别繁琐
阿超
2022/08/16
1.1K0
第三方登录
[认证授权] 1.OAuth2授权
1 OAuth2解决什么问题的? 举个栗子先。小明在QQ空间积攒了多年的照片,想挑选一些照片来打印出来。然后小明在找到一家提供在线打印并且包邮的网站(我们叫它PP吧(Print Photo缩写 ?))
blackheart
2018/01/19
1.9K0
[认证授权] 1.OAuth2授权
Go语言中的OAuth2认证
在网络应用程序开发中,安全性和用户身份验证是至关重要的方面。OAuth2(开放授权2.0)是一种广泛应用于网络身份验证和授权的标准协议。它允许客户端应用程序以安全且受控的方式访问受保护资源,而无需用户提供其凭据。
繁依Fanyi
2024/04/15
1K0
OAuth2简化模式
OAuth 2.0 简化模式(Implicit Flow)是 OAuth 2.0 的一种授权方式,主要用于移动应用或 Web 应用中的前端客户端(例如 JavaScript 应用)的授权。
堕落飞鸟
2023/04/13
2K0
【Spring底层原理高级进阶】【SpringCloud整合Spring Security OAuth2】深入了解 Spring Security OAuth2:底层解析+使用方法+实战
OAuth2(Open Authorization 2.0)是一种用于授权的开放标准协议,用于通过第三方应用程序访问用户在某个服务提供商上存储的资源,而无需共享用户的凭证(例如用户名和密码)。它允许用户授权给第三方应用程序访问受保护的资源,同时确保用户的凭证信息不被直接暴露给第三方应用程序。
苏泽
2024/03/01
2.9K0
【Spring底层原理高级进阶】【SpringCloud整合Spring Security OAuth2】深入了解 Spring Security OAuth2:底层解析+使用方法+实战
认证授权:通过案例学习OAuth2
举个栗子先。小明在QQ*空间积攒了多年的照片,想挑选一些照片来打印出来。然后小明在找到一家提供在线打印并且包邮的网站(我们叫它PP*吧(Print Photo缩写 😂))。
Freedom123
2024/03/29
1460
认证授权:通过案例学习OAuth2
SpringSecurity OAuth2 入门
OAuth(Open Authorization)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
用户8351972
2023/02/27
6320
OAuth2 认证
随着微服务的兴起,OAuth2也火了起来,由于其自身的优势,俨然已成为微服务API服务接口安全防护的首选。
BUG弄潮儿
2022/04/15
6440
OAuth2 认证
Oauth2协议
第三方认证技术方案最主要是解决认证协议的通用标准问题,因为要实现跨系统认证,各系统之间要遵循一定的接口协议。
大忽悠爱学习
2021/12/07
1.4K0
Oauth2协议
SpringCloud-基于Oauth2的SSO单点登录原理解析与实现
单点登录(SSO)是一种身份验证过程,允许用户通过一次登录访问多个系统。本文将深入解析单点登录的原理,并详细介绍如何在Spring Cloud环境中实现单点登录。通过具体的架构图和代码示例,我们将展示SSO的工作机制和优势,帮助开发者更好地理解和应用这一技术。
Damon小智
2024/05/28
2.3K1
SpringCloud-基于Oauth2的SSO单点登录原理解析与实现
Spring Cloud Security OAuth2的授权模式授权码模式(二)
这个配置类将启用资源服务器并配置 HTTP 安全性,使得只有经过身份验证的用户才能访问 /api 路径下的资源。
堕落飞鸟
2023/04/13
1.3K0
Spring Security 与 OAuth2 介绍
OAuth2 角色 resource owner:资源所有者(指用户) resource server:资源服务器存放受保护资源,要访问这些资源,需要获得访问令牌(下面例子中的 Twitter 资源服务器) client:客户端代表请求资源服务器资源的第三方程序(下面例子中的 Quora)客户端同时也可能是一个资源服务器 authrization server:授权服务器用于发放访问令牌给客户端(下面例子中的 Twitter 授权服务器) OAuth2 工作流程例子 客户端 Quora 将自己注册到授
朝雨忆轻尘
2019/06/18
1.5K0
「服务器」Oauth2验证框架之项目实现
Oauth2.0是一个很通用的验证框架,很多编程语言都对其进行了实现,包括Java、PHP、Python、NodeJS、Ruby、NET、Erlang、Go、C等。大家可以在如下页面,查看自己所使用语言的实现方案。
ZhangXianSheng
2019/05/28
3.8K0
OAuth2.0系列博客教程汇总
OAuth 1.0协议(RFC5849)作为一个指导性文档发布,是一个小社区的工作成果。 本标准化规范在OAuth 1.0的部署经验之上构建,也包括其他使用案例以及从更广泛的IETF社区收集到的可扩展性需求。
SmileNicky
2022/07/28
6590
OAuth2.0系列博客教程汇总
OAuth2混合模式
OAuth2混合模式(Hybrid Flow)是一种OAuth2授权模式,它结合了授权码模式和隐式授权模式的优点,可以在保证安全性的同时,提供更好的用户体验。
堕落飞鸟
2023/04/14
8690
OAuth2的定义和运行流程
开放授权(Open Authorization OAuth) 是一种资源提供商用于授权第三方应用代表资源所有者获取有限访问权限的授权机制。由于在整个授权过程中,第三方应用都无法触及用户的密码就可以获取部分资源的使用权限,所以OAuth是开放安全的。
阿提说说
2022/12/02
9280
Shiro框架学习,Shiro与OAuth2集成
目前很多开放平台如新浪微博开放平台都在使用提供开放API接口供开发者使用,随之带来了第三方应用要到开放平台进行授权的问题,OAuth就是干这个的,OAuth2是OAuth协议的下一个版本,相比OAuth1,OAuth2整个授权流程更简单安全了,但不兼容OAuth1,具体可以到OAuth2官网http://oauth.net/2/查看,OAuth2协议规范可以参考http://tools.ietf.org/html/rfc6749。目前有好多参考实现供选择,可以到其官网查看下载。
用户1289394
2021/04/20
5K0
Shiro框架学习,Shiro与OAuth2集成
Spring Security 系列(2) —— Spring Security OAuth2
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
求和小熊猫
2022/06/30
6.3K0
微服务[学成在线] day16:基于Spring Security Oauth2开发认证服务
要想掌握学生的学习情况就需要知道用户的身份信息,记录哪个用户在什么时间学习什么课程;如果用户要购买课程也需要知道用户的身份信息。所以,去管理学生的学习过程最基本的要实现用户的身份认证。
LCyee
2020/08/05
4.4K0
微服务[学成在线] day16:基于Spring Security Oauth2开发认证服务
使用OAuth2实现授权服务
OAuth 2发明之初是为了解决登录认证过程中的安全性问题,使用“委托”的形式使第三方应用获得数据权限及功能。OAuth 2.0协议中,使用访问令牌ACCESS_TOKEN代替传统的账号密码,提高了互联网环境下的安全性。
关忆北.
2022/09/28
1.5K0
使用OAuth2实现授权服务
相关推荐
第三方登录
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验