nextcloud与oauth2集成教程

基础环境

  • Nextcloud 15.0.5
  • oauth2

安装 sociallogin

  1. 在官方app应用商店下载 sociallogin
  2. 解压并拷贝 sociallogin 至 app 目录
  3. 打开 Nextcloud 并在 应用中启用

配置oauth2

  1. 使用管理员账号打开 Nextcloud 找到 sociallogin设置,选择 Custom OAuth2 并添加oauth2信息,如下
  2. 设置只使用oauth2登录,取消系统登录
    编辑 /var/www/html/config/config.php 添加以下配置:

    'social_login_auto_redirect' => true

使用Oauth2注销 Nextcloud

使用中发现点击登出后,Nextcloud只是注销了本身的session,并没有注销oauth2的session,因此会登出失败.
打开 core/Controller/LoginController.php 找到 logout 方法,修改 $response 值如下:

$response = new RedirectResponse('http://10.0.4.3/logout?redirect_uri=http://10.0.4.33:8088');
  • http://10.0.4.3/logout 为oauth2认证系统登出地址

使用用户信息创建组

  1. 在使用oauth2登录成功后,为了与原有Nextcloud用户区分,Nextcloud会在数据库中创建一个用户名为 oauth2 Internal name + 登录名称的用户,这样使用起来及其不方便,我们可以通过修改以下代码,保证用户名正常不带前缀:
  2. 根据返回用户信息中其他信息创建组
  • sociallogin/lib/Controller/LoginController.php

    private function login($uid, Profile $profile)
    {
        $user = $this->userManager->get($uid);
        if (null === $user) {
            $connectedUid = $this->socialConnect->findUID($uid);
            $user = $this->userManager->get($connectedUid);
        }
        if ($this->userSession->isLoggedIn()) {
            if (!$this->config->getAppValue($this->appName, 'allow_login_connect')) {
                throw new LoginException($this->l->t('Social login connect is disabled'));
            }
            if (null !== $user) {
                throw new LoginException($this->l->t('This account already connected'));
            }
            $currentUid = $this->userSession->getUser()->getUID();
            $this->socialConnect->connectLogin($currentUid, $uid);
            return new RedirectResponse($this->urlGenerator->linkToRoute('settings.PersonalSettings.index', ['section' => 'additional']));
        }
        if (null === $user) {
            if ($this->config->getAppValue($this->appName, 'disable_registration')) {
                throw new LoginException($this->l->t('Auto creating new users is disabled'));
            }
            if (
                $profile->email && $this->config->getAppValue($this->appName, 'prevent_create_email_exists')
                && count($this->userManager->getByEmail($profile->email)) !== 0
            ) {
                throw new LoginException($this->l->t('Email already registered'));
            }
            $password = substr(base64_encode(random_bytes(64)), 0, 30);
            $user = $this->userManager->createUser($uid, $password);
            $user->setDisplayName($profile->displayName ?: $profile->identifier);
            $user->setEMailAddress((string)$profile->email);
    
            $newUserGroup = $this->config->getAppValue($this->appName, 'new_user_group');
            if ($newUserGroup) {
                try {
                    $group = $this->groupManager->get($newUserGroup);
                    $group->addUser($user);
                } catch (\Exception $e) {
                }
            }
    
            if ($profile->photoURL) {
                $curl = new Curl();
                try {
                    $photo = $curl->request($profile->photoURL);
                    $avatar = $this->avatarManager->getAvatar($uid);
                    $avatar->set($photo);
                } catch (\Exception $e) {
                }
            }
            $this->config->setUserValue($uid, $this->appName, 'disable_password_confirmation', 1);
            if ($profile->data['departmentName'] !== null) {
                $existGroup = $this->groupManager->get($profile->data['departmentName']);
                if ($existGroup === null) {
                    $newGroup = $this->groupManager->createGroup($profile->data['departmentName']);
                    $newGroup->addUser($user);
                } else {
                    $existGroup->addUser($user);
                }
            }
        }
    
        $this->userSession->completeLogin($user, ['loginName' => $user->getUID(), 'password' => null]);
        $this->userSession->createSessionToken($this->request, $user->getUID(), $user->getUID());
    
        if ($redirectUrl = $this->session->get('login_redirect_url')) {
            return new RedirectResponse($redirectUrl);
        }
    
        $this->session->set('last-password-confirm', time());
    
        return new RedirectResponse($this->urlGenerator->getAbsoluteURL('/'));
    }
  • sociallogin/lib/Provider/CustomOAuth2.php
public function getUserProfile()
    {
        $profileFields = array_filter(
            array_map('trim', explode(',', $this->config->get('profile_fields'))),
            function ($val) {
                return !empty($val);
            }
        );
        $profileUrl = $this->config->get('endpoints')->get('profile_url');

        if (count($profileFields) > 0) {
            $profileUrl .= (strpos($profileUrl, '?') !== false ? '&' : '?') . 'fields=' . implode(',', $profileFields);
        }
        $response = $this->apiRequest($profileUrl);
        if (!isset($response->identifier) && isset($response->id)) {
            $response->identifier = $response->id;
        }
        if (!isset($response->identifier) && isset($response->data->id)) {
            $response->identifier = $response->data->id;
        }
        if (!isset($response->identifier) && isset($response->user_id)) {
            $response->identifier = $response->user_id;
        }
        $data = new Data\Collection($response);
        if (!$data->exists('identifier')) {
            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
        }
        $userProfile = new User\Profile();
        foreach ($data->toArray() as $key => $value) {
            if (property_exists($userProfile, $key)) {
                $userProfile->$key = $value;
            }
        }
        if (!empty($userProfile->email)) {
            $userProfile->emailVerified = $userProfile->email;
        }
        $attributes = new Data\Collection($data->get('attributes'));
        $userProfile->data = [
            "organizationName" => $attributes->get('organizationName'),
            "departmentName" => $attributes->get('departmentName'),
        ];
        if ($attributes->get('name') !== null) {
            $userProfile->displayName = $attributes->get('name');
        }
        return $userProfile;
    }

你可能感兴趣的:(php,cas)