24
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

株式会社ピーアールオー(あったらいいな!を作ります)Advent Calendar 2019

Day 22

Nextcloud + KeycloakでSAML認証する in ラズパイ4

Last updated at Posted at 2019-12-21

はじめに

株式会社ピー・アール・オーのアドベントカレンダー22日目は、
表題の通り、NextcloudとKeycloakを組み合わせてファイルサーバを構築したのでその手順を書き残す。

背景

ツーリング中にドラレコやGoProで撮影した動画を友人内で共有するにあたり、
SFTPを使用してファイル共有をしていた。
(1ファイル4GBくらいあるので、GoogleDriveはあっという間に容量超過した)
さすがにパスワード認証は論外なので公開鍵認証を使用していたところ、以下の運用上の問題が発生した。

  • 秘密鍵を失くすケース(まあわかる)
  • 接続手順を忘れるケース(彼は本当にエンジニアなのだろうか)

失くされる度に公開鍵を登録し直すのは億劫かつ、こんなことのために手順書を用意するのも馬鹿らしいので、
簡単に使えるファイルサーバを立ち上げることにした。

目的

SAML認証の目的

普段よく使うサービス、それこそGoogleアカウントなら忘れないだろうし、
忘れても自分でパスワード再発行してよしなにやってもらえるため。
本当はopenid connectでやりたかったが、外部idp(google)を挟むと認証後Nextcloudが例外吐くので断念。Keycloak単体だと普通に動くんだけど。。。

Nextcloudを使用する目的

オープンソースのオンラインストレージを検索すると引っかかったのはownCloudとNextcloudの2つ。どちらもDropboxライク。
残念なことにownCloudは有償版のみSAML対応であったため、Nextcloudを使用することにした。
詳しくは公式サイトでも見て下さい。

Keycloakを使用する目的

環境

名称 バージョンなど 備考
OS Raspbian GNU/Linux 10 (buster) ラズパイ4
Keycloak 10.0.1 ID管理/認証
Nextcloud 18.0.4 ファイルサーバ
Postgresql 12.1 Nextcloud & Keycloak用DB
nginx 1.14.2 リバプロ

流れ

image.png

構築

各種ミドルウェアの準備

docker-composeはpipで入れた。

$ sudo apt-get install -y nginx
$ sudo curl -fsSL https://get.docker.com/ | sh
$ sudo apt-get -y install python3-dev python3-pip
$ sudo pip3 install docker-compose

Nextcloud、Keycloak、PostgresqlはDockerで入れた。
Keycloakはarmで動くいい感じのイメージが見つからなかったので、Dockerfile書いてビルドした。

$ docker build -t me/keycloak .
Dockerfile
FROM balenalib/raspberry-pi-openjdk:8-stretch

ENV KEYCLOAK_VERSION 10.0.1
ENV JDBC_POSTGRES_VERSION 42.2.12
ENV JBOSS_HOME /data/keycloak

USER root

RUN mkdir /data
WORKDIR /data

RUN curl -LO https://downloads.jboss.org/keycloak/${KEYCLOAK_VERSION}/keycloak-${KEYCLOAK_VERSION}.tar.gz
RUN tar xfp keycloak-${KEYCLOAK_VERSION}.tar.gz --no-same-owner
RUN mv ${JBOSS_HOME}-${KEYCLOAK_VERSION} ${JBOSS_HOME}
RUN rm ${JBOSS_HOME}-${KEYCLOAK_VERSION}.tar.gz
RUN chmod +x ${JBOSS_HOME}/bin/standalone.sh

RUN mkdir ${JBOSS_HOME}/cli
RUN mkdir -p ${JBOSS_HOME}/standalone/deployments/

RUN curl -LO https://jdbc.postgresql.org/download/postgresql-${JDBC_POSTGRES_VERSION}.jar
COPY keycloak-add-user.json ${JBOSS_HOME}/standalone/configuration/keycloak-add-user.json
COPY config.cli ${JBOSS_HOME}/cli/config.cli
RUN sed -i -e "s/{{JDBC_POSTGRES_VERSION}}/${JDBC_POSTGRES_VERSION}/g" ${JBOSS_HOME}/cli/config.cli

RUN ${JBOSS_HOME}/bin/jboss-cli.sh --file=${JBOSS_HOME}/cli/config.cli
RUN rm -rf ${JBOSS_HOME}/standalone/configuration/standalone_xml_history

EXPOSE 8080

CMD [ "/bin/bash", "/data/keycloak/bin/standalone.sh", "-b", "0.0.0.0" ]
  • 設定ファイルについて
設定ファイル名 設定内容
config.cli jboss-cliのコマンドを記述したファイル
keycloak-add-user.json adminユーザの作成
  • config.cli

jboss-cliを実行し、各設定を行っている。
やっていることは以下。

  1. JDBCドライバのインストール
  2. DataSourceの設定
  3. Keycloakのhttpsリダイレクト設定(リバプロをかませるため)
  4. Keycloak管理コンソールのアクセス制御

:information_source: ちなみに
CLIでmodule addを実施するのは非推奨らしいが、今回はやっちゃう。

config.cli
embed-server --server-config=standalone.xml --std-out=echo
module add --name=org.postgresql --resources=postgresql-{{JDBC_POSTGRES_VERSION}}.jar --dependencies=javax.api,javax.transaction.api
/subsystem=undertow/server=default-server/http-listener=default: write-attribute(name=proxy-address-forwarding, value=true)
/subsystem=datasources/data-source=KeycloakDS: remove()
/subsystem=datasources/data-source=KeycloakDS: add(jndi-name=java:jboss/datasources/KeycloakDS,enabled=true,use-java-context=true,use-ccm=true, connection-url=jdbc:postgresql://${env.DB_ADDR:postgres}:5432/${env.DB_DATABASE:keycloak}${env.JDBC_PARAMS:}, driver-name=postgresql)
/subsystem=datasources/data-source=KeycloakDS: write-attribute(name=user-name, value=${env.DB_USER:keycloak})
/subsystem=datasources/data-source=KeycloakDS: write-attribute(name=password, value=${env.DB_PASSWORD:password})
/subsystem=datasources/data-source=KeycloakDS: write-attribute(name=check-valid-connection-sql, value="SELECT 1")
/subsystem=datasources/data-source=KeycloakDS: write-attribute(name=background-validation, value=true)
/subsystem=datasources/data-source=KeycloakDS: write-attribute(name=background-validation-millis, value=60000)
/subsystem=datasources/data-source=KeycloakDS: write-attribute(name=flush-strategy, value=IdleConnections)
/subsystem=datasources/jdbc-driver=postgresql:add(driver-name=postgresql, driver-module-name=org.postgresql, driver-xa-datasource-class-name=org.postgresql.xa.PGXADataSource)
/subsystem=keycloak-server/spi=connectionsJpa/provider=default:write-attribute(name=properties.schema,value=${env.DB_SCHEMA:public})
/subsystem=undertow/configuration=filter/expression-filter=ipAccess:add(,expression="path-prefix[/auth/admin] -> ip-access-control(acl={'192.168.0.0/24 allow'})")
/subsystem=undertow/server=default-server/host=default-host/filter-ref=ipAccess:add()
stop-embedded-server
  • keycloak-add-user.json
keycloak-add-user.json
[ {
  "realm" : "master",
  "users" : [ {
    "username" : "admin",
    "enabled" : true,
    "credentials" : [ {
      "type" : "password",
      "secretData" : "{\"value\":\"3MLtOqxjN3tKhaXmIwSQhTLBCdWHf1FvsdeHibw49glSj5Gj7L/8Dac7P399mJlpsOJ/20Wr3OmWBA+E/BzqhA==\",\"salt\":\"eLxa1xVzxfsGu7qlYsZosg==\"}",
      "credentialData" : "{\"hashIterations\":100000,\"algorithm\":\"pbkdf2-sha256\"}"
    } ],
    "realmRoles" : [ "admin" ]
  } ]
} ]

起動はdocker-composeを使用する。
全部同じネットワークに乗っけて、ローカルからのみアクセスOKとしている。
また、コンテナ立ち上げ時にNextcloud、KeycloakのDBをそれぞれ作成するため、initdbディレクトリにSQLを放り込んでおく。
見よう見まねで書いているので、質についてはなんともいえない。

docker-compose.yml
version: '3'

services:
  postgres:
      image: postgres
      container_name: 'postgres'
      volumes:
        - ./postgres_data:/var/lib/postgresql/data
        - ./initdb:/docker-entrypoint-initdb.d
      ports:
      - "127.0.0.1:5432:5432"
      environment:
        POSTGRES_USER: postgres
        POSTGRES_PASSWORD: password
      restart: always
      network_mode: bridge
  nextcloud:
      image: nextcloud
      container_name: 'nextcloud'
      volumes:
        - ./nextcloud:/var/www/html
      ports:
      - "127.0.0.1:10443:443"
      - "127.0.0.1:10080:80"
      restart: always
      environment:
      - POSTGRES_HOST=postgres
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=password
      - NEXTCLOUD_ADMIN_USER=admin
      - NEXTCLOUD_ADMIN_PASSWORD=password
      - NEXTCLOUD_TRUSTED_DOMAINS=cloud.example.com
      - OVERWRITEHOST=cloud.example.com
      - OVERWRITEPROTOCOL=https
      links:
      - postgres
      network_mode: bridge
  keycloak:
      image: me/keycloak
      container_name: 'keycloak'
      volumes:
          - ./deployments:/data/keycloak/standalone/deployments/
      restart: always
      links:
      - postgres
      ports:
      - 127.0.0.1:8080:8080
      network_mode: bridge
  • initdbに格納するSQL
init.sql
CREATE USER keycloak WITH PASSWORD 'password';
CREATE DATABASE keycloak OWNER keycloak;
CREATE USER nextcloud WITH PASSWORD 'password';
CREATE DATABASE nextcloud OWNER nextcloud;

リバースプロキシの設定

Dockerにプロキシする設定。
以下のようなconfファイルを作成し、/etc/nginx/conf.dに放り込む。
http ⇒ httpsのリダイレクトは省略。

proxy.conf
### nextcloud ###
server {
    listen 443;
    client_max_body_size 10G;
    server_name cloud.example.com;
    ssl on;
    ssl_certificate /etc/nginx/cert/privatekey.pem;
    ssl_certificate_key /etc/nginx/cert/server.crt;

    location / {
        proxy_pass http://localhost:10080;
        proxy_redirect http:// https://;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
### keycloak ###
server {
    listen 443;
    server_name sso.example.com;
    ssl on;
    ssl_certificate /etc/nginx/cert/privatekey.pem;
    ssl_certificate_key /etc/nginx/cert/server.crt;

    location / {
        proxy_pass http://localhost:8080;
        proxy_redirect http:// https://;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

SAML署名鍵 & 証明書の作成

SAMLで使用する鍵と証明書を作成しておく。
DN項目はCN含めすべて空でよい。

$ openssl req  -nodes -new -x509 --days 10000  -keyout private.key -out public.crt

起動

この後の設定は各システムのGUIで行うので立ち上げる。

$ docker-compose up -d

Keycloakの設定 - レルム作成

https://sso.example.com/authにアクセスすると、ウェルカムページが表示される。
Administration Consoleを選択し、管理コンソールにログインする。

image.png

image.png

レルムの作成

レルムの追加から、nextcloudレルムを作成する。

image.png

レルム証明書の取得

レルムの設定 ⇒ から、アルゴリズムRS256の証明書を表示し、コピーしておく。
image.png

Nextcloudの設定

AdminユーザでNextcloudにログインし、右上のアイコンからアプリ連携 から SSO & SAML authenticationをインストールする。
image.png

SSOとSAML認証の設定

右上のアイコンから設定 ⇒ 左メニューのSSOとSAML認証から設定画面に入り、
Identity providerを追加するを押して設定を作成する。
設定内容は以下。

  • 一般
設定項目 設定内容
UIDをマップする属性 username
IPプロバイダオプションの表示名 お好みで
  • Service Providerデータ
設定項目 設定内容
名前IDの形式 指定なし
サービスプロバイダのX.509 証明書 先ほど作ったpublic.crtをそのまま貼り付ける
サービスプロバイダーの秘密鍵 先ほど作ったprivate.keyをそのまま貼り付ける
  • Identity Providerデータ
設定項目 設定内容
IdPエンティティの識別子 https://Keycloakのホスト名/auth/realms/レルム名
SPが認証要求メッセージをを送信するIdPのURIターゲット https://Keycloakのホスト名/auth/realms/レルム名/protocol/saml
  • オプションのIdentity Provider設定
設定項目 設定内容
SPが認証要求メッセージをを送信するIdPのURIターゲット https://Keycloakのホスト名/auth/realms/レルム名/protocol/saml
IdPの公開X.509証明書 -----BEGIN CERTIFICATE-----さっきKeycloak上で控えた証明書-----END CERTIFICATE-----
  • 属性マッピング
設定項目 設定内容
表示名をにマップする属性(原文ママ) username
電子メールアドレスをマップする属性 email
  • セキュリティ設定

以下にチェックを入れる。

設定項目
このSPによって送信された samlp:AuthnRequest メッセージが署名されるかどうかを示します。[SPのメタデータがこの情報を提供する]
このSPによって送信された samlp:logoutRequest メッセージが署名されるかどうかを示します。
このSPによって送信された samlp:logoutResponse メッセージが署名されるかどうかを示します。
このSPが受信したsamlp:Responsesamlp:LogoutRequest、およびsamlp:LogoutResponse要素が署名されるための要件を示します。
ここのSPによって受信されたsaml:Assertion要素が署名されるための要件を示します。 [SPのメタデータはこの情報を提供する]

設定完了後、最下部のボタンから、メタデータXMLをダウンロードする。

  • 設定例
    image.png

Keycloakの設定 - クライアント設定

クライアントの作成

SAML用クライアントを新規作成する。
ここで、インポートを選択し、先ほどNextcloud上でダウンロードしたメタデータXMLを選択する。
すると、以下画面のように設定項目が自動的に投入される。

  • 設定例
    image.png

クライアントの設定

クライアントを保存すると設定画面に移動するため、そのまま設定する。

設定

以下の設定項目のみ修正する。

設定項目 設定内容
ルートURL https://Nextcloudのホストネーム
有効なリダイレクトURL https://Nextcloudのホストネーム/*
  • 設定例
    image.png

マッパー

Nextcloudユーザーはusernameemailが必須属性なのでマッパーも設定する。

  • マッパー
名前 マッパータイプ プロパティ Friendly Name SAML Attribute Name SAML Attribute NameFormat
username User Property username username username Basic
email User Property email email email Basic
  • 設定例
    image.png

クライアントスコープの設定

左メニューのクライアントスコープからrole_listを選択 ⇒ マッパーからrole_listを選択 ⇒ Single Role Attributeオンにしておく。
この設定を入れないと、SAML認証時、Nextcloudが謎の例外を吐いてしまい認証に失敗する。

  • 設定例
    image.png

  • 散り様
    image.png

外部idp設定

Googleの設定

Googleアカウントによる認証を行うには、まず、GoogleのAPIコンソールから認証情報を作成する。

  • 新しいプロジェクトを作成
    image.png

  • OAuth同意画面を作成(G Suiteは私用しないのでUserTypeは外部とする)
    image.png

  • 承認済みドメインには最上位のドメイン名を登録する。
    image.png

  • 保存後
    image.png

  • 認証情報を作成する。(OAuth クライアントIDを選択)
    image.png

  • 認証情報の設定内容
    image.png

  • 登録後(クライアントIDとシークレットが発行されるので控えておく)
    image.png

Keycloakの設定

左メニューからアイデンティティプロバイダーを選択し、Googleを選択し、設定画面に入る。

  • 設定内容(差分のみ)
設定項目 設定内容
クライアントID さっき控えたクライアントID
クライアントシークレット さっき控えたクライアントシークレット
デフォルトスコープ openid profile email
  • 設定例
    image.png

拡張モジュール作成/設定

実はここまでの設定でもうNextcloudにGoogleアカウントでログインすることができる。
ただ、このままではGoogleアカウント持ってれば誰でもウェルカム状態なので、
Keycloakに拡張認証モジュールを投入し、Keycloak上にアカウントが存在しない人をたたき出すようにする。
今回拡張したいのはFirst Broker Loginなので、AbstractIdpAuthenticatorを継承してモジュールを作成した。

認証モジュールの流れ

  1. Google経由のログインが初めてなら拡張モジュールに入る
  2. Googleから送られてきたユーザー情報のメールアドレスで、Keycloakにアカウントが作られているかチェック
  3. 作られていなければ認証NGにしてたたき出す
  4. 作られていたらGoogleとアカウントリンクして認証OKにする

ファイル構成

認証モジュールの作成には、少なくとも認証モジュール本体、ファクトリー、クラス登録用定義ファイルの3種が必要。

  • ファイル構成例
    image.png

コード

  • 認証モジュール本体
IpdAccountExistsAuthenticator.java
package local.example;

import org.jboss.logging.Logger;
import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.AuthenticationFlowError;
import org.keycloak.authentication.AuthenticationFlowException;
import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator;
import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext;
import org.keycloak.broker.provider.BrokeredIdentityContext;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;

import java.util.Objects;

public class IpdAccountExistsAuthenticator extends AbstractIdpAuthenticator {

    private static Logger logger = Logger.getLogger(IpdAccountExistsAuthenticator.class);

    /**
     * 認証処理
     *
     * @param context
     * @param serializedCtx
     * @param brokerContext
     */
    @Override
    protected void authenticateImpl(AuthenticationFlowContext context, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext) {

        logger.info("Start IpdAccountExistsAuthenticator");

        // ユーザがKeycloakに登録済みであればOK
        UserModel user = context.getSession().users().getUserByUsername(brokerContext.getEmail(), context.getRealm());

        if (Objects.isNull(user)) {
            // ユーザが取れなければ認証失敗にする
            throw new AuthenticationFlowException("そんなユーザいません : " + brokerContext.getEmail(), AuthenticationFlowError.UNKNOWN_USER);
        }

        user.setEnabled(true);
        user.setEmail(brokerContext.getEmail());
        user.setFirstName(brokerContext.getFirstName());
        user.setLastName(brokerContext.getLastName());

        logger.info("認証OK : " + user.getUsername());

        // 認証成功
        context.setUser(user);
        context.getAuthenticationSession().setAuthNote(BROKER_REGISTERED_NEW_USER, "true");
        context.getAuthenticationSession().setAuthenticatedUser(user);
        context.success();
    }

    @Override
    protected void actionImpl(AuthenticationFlowContext context, SerializedBrokeredIdentityContext
            serializedCtx, BrokeredIdentityContext brokerContext) {

    }

    @Override
    public boolean requiresUser() {
        return false;
    }

    @Override
    public boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user) {
        return false;
    }
}
  • ファクトリー
IpdAccountExistsAuthenticatorFactory.java
package local.example;

import org.keycloak.authentication.Authenticator;
import org.keycloak.authentication.AuthenticatorFactory;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.provider.ProviderConfigProperty;

import java.util.List;

public class IpdAccountExistsAuthenticatorFactory implements AuthenticatorFactory {

    public static final String ID = "exists-account-from-keycloak";
    public static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = {
            AuthenticationExecutionModel.Requirement.ALTERNATIVE,
            AuthenticationExecutionModel.Requirement.REQUIRED,
            AuthenticationExecutionModel.Requirement.DISABLED};

    @Override
    public Authenticator create(KeycloakSession keycloakSession) {
        return new IpdAccountExistsAuthenticator();
    }

    @Override
    public void init(org.keycloak.Config.Scope scope) {

    }

    @Override
    public void postInit(KeycloakSessionFactory keycloakSessionFactory) {

    }

    @Override
    public void close() {

    }

    @Override
    public String getId() {
        return ID;
    }

    @Override
    public String getReferenceCategory() {
        return "exists-account";
    }

    @Override
    public boolean isConfigurable() {
        return true;
    }

    @Override
    public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
        return REQUIREMENT_CHOICES;
    }

    @Override
    public String getDisplayType() {
        return ID;
    }

    @Override
    public String getHelpText() {
        return "ipd exists accoount";
    }

    public boolean isUserSetupAllowed() {
        return true;
    }

    public List<ProviderConfigProperty> getConfigProperties() {
        return null;
    }
}
  • クラス登録用定義ファイル
org.keycloak.authentication.AuthenticatorFactory
local.example.IpdAccountExistsAuthenticatorFactory

ビルド

上記ファイルをビルドしてjarを生成する。
pomはこんな感じにしてmvn installした。

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>club.honatsugi-ol.sso</groupId>
    <version>1.0-SNAPSHOT</version>
    <name>IDP Exists</name>
    <description/>
    <artifactId>idp_account_exists</artifactId>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <keycloak.version>10.0.1</keycloak.version>
        <version.wildfly.maven.plugin>1.1.0.Final</version.wildfly.maven.plugin>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-core</artifactId>
            <version>${keycloak.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-server-spi</artifactId>
            <version>${keycloak.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-server-spi-private</artifactId>
            <version>${keycloak.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-services</artifactId>
            <version>${keycloak.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.logging</groupId>
            <artifactId>jboss-logging</artifactId>
            <version>3.4.1.Final</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>idp-account-exists</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Dependencies>org.keycloak.keycloak-services</Dependencies>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

デプロイ

Keycloakのホームディレクトリ/standalone/deploymentsに産み出されたjarを放り込むと、ホットデプロイしてくれる。

認証フローの作成

左メニューの認証から、以下のような認証フローを作成する。
設定が複雑なので、デフォルトで存在するフローをコピー ⇒ アクションからExecution全削除 ⇒ Executionを追加から拡張モジュールを追加とすると楽。

  • 設定例
    image.png

作成したフローの設定

左メニューのアイデンティティプロバイダーからさっき作ったgoogleを選択し、
初回ログインフローにフローを設定する。

  • 設定例
    image.png

動作確認

ログイン成功(登録済みユーザ)

  • Keycloakにユーザを登録
    image.png

  • SSO & SAMLログインを選択
    image.png

  • Keycloakのログイン画面に飛ぶのでGoogleを選択
    image.png

  • テストユーザを選択してログイン
    image.png

  • ログイン成功
    image.png

ログイン失敗(未登録ユーザ)

  • Keycloak上からテストユーザを抹殺して再度ログイン
    image.png

  • 弾いた
    image.png

  • ログ
    image.png

メモ

NextcloudのSSOとSAML認証の設定の保存場所

設定はNextcloudDBのoc_appconfigテーブルに存在する。
appidカラムをuser_samlで絞ると見つけるのが楽。
ガチャガチャいじってたらデータが壊れ、設定が保存されなくなってしまったが、レコード修正したら治った。

Keycloakのリモートデバッグ

standalone.confにこんな設定があるので、コメント解除してKeycloakを再起動してやればOK。
ポート開けてやればIDEから接続可能。

standalone.conf
# Sample JPDA settings for remote socket debugging
#JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"
docker-compose.yml
      ports:
      - 127.0.0.1:8080:8080
      - 8787:8787

終わりに

ラズパイ4でもなかなか機敏に動く。感動した。
もともとこのシステムはラズパイ2で無理矢理動かしていたが、サムネ生成の速度とか雲泥の差。
記事書くついでに移植したが、やってよかった。。。

24
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?