PoC for an OAuth2/OpenID Connect provider using ORY Hydra.
This repository has been archived on 2022-07-28. You can view files and clone it, but cannot push or open issues or pull requests.
Go to file
2021-01-01 15:43:07 +01:00
app Add logger to oidc_callback 2021-01-01 15:43:07 +01:00
cmd Implement client certificate login 2021-01-01 14:21:26 +01:00
common Translations for login form 2021-01-01 12:40:12 +01:00
idp Implement client certificate login 2021-01-01 14:21:26 +01:00
templates Implement client certificate login 2021-01-01 14:21:26 +01:00
.gitignore Refactor i18n, add templating for resource app 2021-01-01 09:20:49 +01:00
active.de.toml Implement client certificate login 2021-01-01 14:21:26 +01:00
active.en.toml Implement client certificate login 2021-01-01 14:21:26 +01:00
go.mod Implement database access for user information 2021-01-01 12:28:33 +01:00
go.sum Implement database access for user information 2021-01-01 12:28:33 +01:00
README.md Refactor i18n, add templating for resource app 2021-01-01 09:20:49 +01:00
translate.de.toml Implement client certificate login 2021-01-01 14:21:26 +01:00

Proof of concept OpenID Connect / OAuth server with ORY Hydra

This repository contains a proof of concept implementation for an identity provider and an application using OIDC. ORY Hydra is used for the actual OAuth2 / OpenID Connect operations. The implementation in this repository provides the UI components that are required by Hydra.

Setup

  • create certificates for the IDP, the application and Hydra. You can use the testca from the CAcert developer setup like this:

    1. create signing requests

      mkdir certs
      cd certs
      openssl req -new -newkey rsa:3072 -nodes \
        -keyout hydra.cacert.localhost.key \
        -out hydra.cacert.localhost.csr.pem \
        -subj /CN=hydra.cacert.localhost \
        -addext subjectAltName=DNS:hydra.cacert.localhost,DNS:auth.cacert.localhost
      openssl req -new -newkey rsa:3072 -nodes \
        -keyout idp.cacert.localhost.key \
        -out idp.cacert.localhost.csr.pem \
        -subj /CN=idp.cacert.localhost \
        -addext subjectAltName=DNS:idp.cacert.localhost,DNS:login.cacert.localhost,DNS:register.cacert.localhost
      openssl req -new -newkey rsa:3072 -nodes \
        -keyout app.cacert.localhost.key \
        -out app.cacert.localhost.csr.pem \
        -subj /CN=app.cacert.localhost \
        -addext subjectAltName=DNS:app.cacert.localhost
      cp *.csr.pem $PATH_TO_DEVSETUP_TESTCA/
      
    2. Use the CA to sign the certificates

      pushd $PATH_TO_DEVSETUP_TESTCA/
      for csr in hydra idp app; do
          openssl ca -config ca.cnf -name class3_ca -extensions server_ext \
          -in ${csr}.cacert.localhost.csr.pem \
          -out ${csr}.cacert.localhost.crt.pem -days 365
      done
      popd
      cp $PATH_TO_DEVSETUP_TESTCA/{hydra,idp,app}.cacert.localhost.crt.pem .
      
  • install Hydra according to their documentation

  • setup the Hydra database

    sudo -i -u postgres psql
    > CREATE DATABASE hydra_local ENCODING utf-8;
    > CREATE USER hydra_local WITH PASSWORD '${YOUR_POSTGRESQL_PASSWORD}';
    > GRANT CONNECT, CREATE ON DATABASE hydra_local TO hydra_local;
    
    hydra migrate sql "postgres://hydra_local:${YOUR_POSTGRESQL_PASSWORD}@localhost:5432/hydra_local"
    
  • create a configuration file for Hydra i.e. hydra.yaml:

    serve:
      admin:
        host: hydra.cacert.localhost
      public:
        host: auth.cacert.localhost
      tls:
        cert:
          path: certs/hydra.cacert.localhost.crt.pem
        key:
          path: certs/hydra.cacert.localhost.key
    dsn: 'postgres://hydra_local:${YOUR_POSTGRESQL_PASSWORD}@localhost:5432/hydra_local'
    
    webfinger:
      oidc_discovery:
        supported_claims:
          - email
          - email_verified
          - given_name
          - family_name
          - middle_name
          - name
          - birthdate
          - zoneinfo
          - locale
          - https://cacert.localhost/groups
        supported_scope:
          - profile
          - email
    
    oauth2:
      expose_internal_errors: false
    
    urls:
      login: https://login.cacert.localhost:3000/login
      consent: https://login.cacert.localhost:3000/consent
      logout: https://login.cacert.localhost:3000/logout
      error: https://login.cacert.localhost:3000/error
      post_logout_redirect: https://login.cacert.localhost:3000/logout-successful
      self:
        public: https://auth.cacert.localhost:4444/
        issuer: https://auth.cacert.localhost:4444/
    
    secrets:
      system:
        - "${YOUR SECRET FOR HYDRA}"
    
  • add entries for auth.cacert.localhost and hydra.cacert.localhost to /etc/hosts

    ::1 auth.cacert.localhost hydra.cacert.localhost
    

    This is required to allow Hydra to start properly

  • create an OIDC client configuration for the demo application

    hydra clients create --endpoint https://hydra.cacert.localhost:4445/ \
      --callbacks https://app.cacert.localhost:4000/callback \
      --logo-uri https://register.cacert.localhost:3000/images/app.png \
      --name "Client App Demo" \
      --scope "openid offline_access profile email" \
      --post-logout-callbacks https://app.cacert.localhost:4000/after-logout \
      --client-uri https://register.cacert.localhost:3000/info/app
    

    the command returns a client id and a client secret that you need to configure for the demo application

  • create a configuration for the IDP

    The IDP requires a strong random key for its CSRF cookie. You can generate such a key using the following openssl command:

    openssl rand -base64 32
    

    Use this value and create idp.toml:

    [security]
    csrf.key = "<32 bytes of base64 encoded data>"
    
  • create a configuration for the Demo application

    You will need a 32 byte and a 64 byte random secret for the session authentication and encryption keys:

    openssl rand -base64 64
    openssl rand -base64 32
    
    [oidc]
    client-id = "<client id from hydra clients invocation>"
    client-secret = "<client secret from hydra clients invocation>"
    
    [session]
    auth-key = "<64 bytes of base64 encoded data>"
    enc-key = "<32 bytes of base64 encoded data>"
    

Now you can start Hydra, the IDP and the demo app in 3 terminal windows:

hydra serve all --config hydra.yaml
go run cmd/idp/main.go
go run cmd/app/main.go

Visit https://app.cacert.localhost:4000/ in a Browser and you will be directed through the OpenID connect authorization code flow.

Translations

This application uses go-i18n for internationalization (i18n) support.

The translation workflow needs the go18n binary which can be installed via

go get -u  github.com/nicksnyder/go-i18n/v2/goi18n

To extract new messages from the code run

goi18n extract .

Then use

goi18n merge active.*.toml

to create TOML files for translation as translate.<locale>.toml. After translating the messages run

goi18n merge active.*.toml translate.*.toml

to merge the messages back into the active translation files. To add a new language you need to add the language code to the languages configuration option (default is defined in the configmap in cmd/idp/main.go and cmd/app/main.go).