authentik实践之二、配置oAuth2/OIDC集成Showdoc

authentik 创建 应用程序、提供程序(application、provider)

file
file
(Tips: 这里 应用的重定向地址,后面来补,因为要填写 具体应用的回调地址,一般要在 配置应用时才能看到)
file
(Tips: 授权绑定逻辑,要注意,默认不绑定 则所有用户 均有访问权限)
file

应用程序 绑定用户/用户组(作用:授权 用户/用户组 有权限访问 该应用)

file

将 authentik 提供程序 高级协议设置处 Subject 模式:改为用户名(见图)

file

authentik 对接 showdoc

## 需要获取的信息如下
    Client id:
    Client secret: 要点击 编辑才能看到
    Oauth host:
    Authorize path:
    AccessToken path:
    User info path:
    callback url(showdoc应用回调地址): https://wiki.atstm.cc/server/?s=/api/extLogin/oauth2

file

(Tips: 将 Showdoc 这里的回调地址,填写到 authentik provider 程序的重定向 处,如下图)
file
file

存在的问题(showdoc 3.4.1版本)

## 已向showdoc 提issue
     https://github.com/star7th/showdoc/issues/2350

## 问题一、当你按照上述对接后,确实能成功登录,但当你 authentik 用户 没有填写显示名称时,showdoc无法完成认证,因为showdoc会认为 未获取到用户信息,其authentik userinfo接口获取到信息格式如下
{
  "sub": "aaa",
  "email": "aaa@gmail.com",
  "email_verified": true,
  "name": "",
  "given_name": "",
  "preferred_username": "aaa",
  "nickname": "aaa",
  "groups": ["search"]
}

## 问题二、当 authentik 用户填写了显示名, showdoc 会将 用户名 和显示名称 都设置成为 你authentik 设置的显示名
    一般我们会将 authentik 用户名 设置为zhangsan, 显示名设置为 张三,但是你在 showdoc 这边却是 用户名 显示名都是张三

修复问题

## 修复方案,进入showdoc 容器,找到 ExtLoginController.class.php 文件,修改 getUserNameFromOAuth2 函数内容
     目的:实现 用 preferred_username 作为showdoc的用户名,用name或者given_name 作为显示名

## 进入showdoc 容器,查找名为 ExtLoginController.class.php 的文件,(会找到两个,其md5都是一样的)
    docker exec -it showdoc bash
    11f4124210ab:/showdoc_data/html# find / -name ExtLoginController.class.php
    /var/www/html/server/Application/Api/Controller/ExtLoginController.class.php
    /showdoc_data/html/server/Application/Api/Controller/ExtLoginController.class.php

    # 对比md5 发现是一样的
    11f4124210ab:/showdoc_data/html# md5sum /showdoc_data/html/server/Application/Api/Controller/ExtLoginController.class.php
    5353b683dd638e8d1c29b857d1197cdd  /showdoc_data/html/server/Application/Api/Controller/ExtLoginController.class.php
    11f4124210ab:/showdoc_data/html# md5sum /var/www/html/server/Application/Api/Controller/ExtLoginController.class.php
    5353b683dd638e8d1c29b857d1197cdd  /var/www/html/server/Application/Api/Controller/ExtLoginController.class.php

    # 备份一份,进行修改
    11f4124210ab:/showdoc_data/html# cp /showdoc_data/html/server/Application/Api/Controller/ExtLoginController.class.php ExtLoginController.class.php.bak

## 编辑 ExtLoginController.class.php 修改函数(上述两个文件都要修改,建议修改一个,然后用其覆盖另一个)
    vi /showdoc_data/html/server/Application/Api/Controller/ExtLoginController.class.php
## 原函数内容
    private function getUserNameFromOAuth2($array)                                                                                                                                                          
    {                                                                                                                                                                                                       
        $keysToCheck = ["preferred_username", "name", "username", "login"];                                                                                                                                 

        foreach ($array as $key => $value) {                                                                                                                                                                
            if (!is_array($value) && in_array($key, $keysToCheck, true)) {                                                                                                                                  
                return $value; // ....................................                                                                                                                                      
            }                                                                                                                                                                                               
        }                                                                                                                                                                                                   

        foreach ($array as $value) {                                                                                                                                                                        
            if (is_array($value)) {                                                                                                                                                                         
                $username = $this->getUserNameFromOAuth2($value); // .....................                                                                                                                  
                if ($username) {                                                                                                                                                                            
                    return $username; // ...........................                                                                                                                                        
                }                                                                                                                                                                                           
            }                                                                                                                                                                                               
        }                                                                                                                                                                                                   

        return false; // ........................... false                                                                                                                                                  
    }  

## 改后函数内容
    private function getUserNameFromOAuth2($array)
    {
        $keysToCheck = ["preferred_username", "username", "name", "login", "email", "sub"];

        foreach ($array as $key => $value) {
            if (!is_array($value) && in_array($key, $keysToCheck, true)) {
                // 如果是 email,就拆掉 @domain,只取前缀
                if ($key === "email") {
                    return explode('@', $value)[0];
                }
                return $value;
            }
        }

        // 递归搜索嵌套数组
        foreach ($array as $value) {
            if (is_array($value)) {
                $username = $this->getUserNameFromOAuth2($value);
                if ($username) {
                    return $username;
                }
            }
        }

        return false;
    }

## 修改完成后,退出容器,重启容器(或者重新机器后再次验证,建议删除showdoc 这边之前同步的用户,重新认证,你会发现 用户名 和 显示名  都能一一匹配了)

file

声明:本文为原创,作者为 辣条①号,转载时请保留本声明及附带文章链接:https://boke.wsfnk.com/archives/1486.html
谢谢你请我吃辣条谢谢你请我吃辣条

如果文章对你有帮助,欢迎点击上方按钮打赏作者

最后编辑于:2025/6/2作者: 辣条①号

目标:网络规划设计师、系统工程师、ceph存储工程师、云计算工程师。 不负遇见,不谈亏欠!

暂无评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

arrow grin ! ? cool roll eek evil razz mrgreen smile oops lol mad twisted wink idea cry shock neutral sad ???

文章目录