All Projects → i-core → werther

i-core / werther

Licence: MIT License
An Identity Provider for ORY Hydra over LDAP

Programming Languages

go
31211 projects - #10 most used programming language
CSS
56736 projects
javascript
184084 projects - #8 most used programming language
Dockerfile
14818 projects

Projects that are alternatives of or similar to werther

Hydra
OpenID Certified™ OpenID Connect and OAuth Provider written in Go - cloud native, security-first, open source API security for your infrastructure. SDKs for any language. Compatible with MITREid.
Stars: ✭ 11,884 (+11437.86%)
Mutual labels:  identity, oauth2, hydra, openid-connect
Authing
🔥Authing - IDaaS/IAM solution that can Auth to web and mobile applications.
Stars: ✭ 247 (+139.81%)
Mutual labels:  ldap, identity, oauth2, openid-connect
OpenAM
OpenAM is an open access management solution that includes Authentication, SSO, Authorization, Federation, Entitlements and Web Services Security.
Stars: ✭ 476 (+362.14%)
Mutual labels:  ldap, oauth2, active-directory
Identityserver4
OpenID Connect and OAuth 2.0 Framework for ASP.NET Core
Stars: ✭ 8,428 (+8082.52%)
Mutual labels:  identity, oauth2, openid-connect
logto
🧑‍🚀 Logto helps you build the sign-in, auth, and user identity within minutes. We provide an OIDC-based identity service and the end-user experience with username, phone number, email, and social sign-in, with extendable multi-language support.
Stars: ✭ 3,421 (+3221.36%)
Mutual labels:  identity, oauth2, openid-connect
Django Oidc Provider
OpenID Connect and OAuth2 provider implementation for Djangonauts.
Stars: ✭ 320 (+210.68%)
Mutual labels:  identity, oauth2, openid-connect
Jpproject.identityserver4.adminui
🔧 ASP.NET Core 3 & Angular 8 Administration Panel for 💞IdentityServer4 and ASP.NET Core Identity
Stars: ✭ 717 (+596.12%)
Mutual labels:  identity, oauth2, openid-connect
Zitadel
ZITADEL - Cloud Native Identity and Access Management
Stars: ✭ 105 (+1.94%)
Mutual labels:  identity, oauth2, openid-connect
Identitymodel
.NET standard helper library for claims-based identity, OAuth 2.0 and OpenID Connect.
Stars: ✭ 693 (+572.82%)
Mutual labels:  identity, oauth2, openid-connect
Oauthlib
A generic, spec-compliant, thorough implementation of the OAuth request-signing logic
Stars: ✭ 2,323 (+2155.34%)
Mutual labels:  identity, oauth2, openid-connect
Caddy Auth Portal
Authentication Plugin for Caddy v2 implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0 (Github, Google, Facebook, Okta, etc.), SAML Authentication
Stars: ✭ 291 (+182.52%)
Mutual labels:  ldap, oauth2, openid-connect
Cierge
🗝️ Passwordless OIDC authentication done right
Stars: ✭ 1,245 (+1108.74%)
Mutual labels:  identity, oauth2, openid-connect
Identitybase
IdentityBase is a Universal Identity Platform for web, mobile and IoT built on top of IdentityServer.
Stars: ✭ 112 (+8.74%)
Mutual labels:  identity, oauth2, openid-connect
External Auth Server
easy auth for reverse proxies
Stars: ✭ 189 (+83.5%)
Mutual labels:  ldap, oauth2, openid-connect
Nginx Sso
SSO authentication provider for the auth_request nginx module
Stars: ✭ 195 (+89.32%)
Mutual labels:  ldap, oauth2, openid-connect
ldap2json
The ldap2json script allows you to extract the whole LDAP content of a Windows domain into a JSON file.
Stars: ✭ 56 (-45.63%)
Mutual labels:  ldap, active-directory
GoogleSignIn-iOS
Enables iOS and macOS apps to sign in with Google.
Stars: ✭ 198 (+92.23%)
Mutual labels:  oauth2, openid-connect
yii-auth-client
Yii Framework external authentication via OAuth and OpenID Extension
Stars: ✭ 20 (-80.58%)
Mutual labels:  oauth2, openid-connect
AD-webmanager
A web interface for administration of Active Directory Domains, made in Python, with focus on easy of use and simplicity.
Stars: ✭ 26 (-74.76%)
Mutual labels:  ldap, active-directory
Linux-Active-Directory-join-script
Active directory Join script for Ubuntu, Debian, CentOS, Linux Mint, Fedora, Kali, Elementary OS and Raspbian with built in failchcheck and debugmode for Ubuntu. "The most advanced and updated AD join script on GITHUB for Linux"
Stars: ✭ 97 (-5.83%)
Mutual labels:  ldap, active-directory

Werther 1

GoDoc Build Status codecov Go Report Card

Werther is an Identity Provider for ORY Hydra over LDAP. It implements Login And Consent Flow and provides basic UI.

screenshot

Features

  • Support Active Directory;
  • Mapping LDAP attributes to OpenID Connect claims;
  • Mapping LDAP groups to user roles;
  • OAuth 2.0 scopes;
  • Caching users roles;
  • UI customization.

Limitations

  • Werther grants all requested permissions to a client without displaying the consent page;
  • Werther confirms a logout request without displaying the logout confirmation page.

Requirements

ORY Hydra v1.0.0-rc.12 or higher.

Table of Contents

Installing

From Docker

docker pull icoreru/werther

From sources

go install ./...

Configuration

The application is configured via environment variables. Names of the environment variables starts with prefix WERTHER_. See a list of the environment variables using the command:

werther -h

User roles

In LDAP user's roles are groups in which a user is a member.

The environment variable WERTHER_LDAP_ROLE_DN is a DN for searching roles.

For example, create an OU that repserents an application, and then in the created OU create groups that represent application's roles:

dc=com
|-- dc=example
    |-- ou=AppRoles
        |-- ou=App1
            |-- cn=app1_role1 (objectClass="group", description="role1")
            |-- cn=app1_role2 (objectClass="group", description="role2")

Run Werther with the environment variable WERTHER_LDAP_ROLE_DN that equals to ou=AppRoles,dc=example,dc=com.

In the above example Werther returns user's roles as a value of the user role's claim https://github.com/i-core/werther/claims/roles.

{
    "https://github.com/i-core/werther/claims/roles": {
        "App1": ["role1", "role2"],
    }
}

To customize the roles claim's name you should set a value of the environment variable WERTHER_LDAP_ROLE_CLAIM. Also you should map the custom name of the roles' claim to a roles's scope using the environment variable WERTHER_IDENTP_CLAIM_SCOPES (the name must be URL encoded):

env WERTHER_LDAP_ROLE_CLAIM=https://my-company.com/claims/roles                                                                                     \
    WERTHER_IDENTP_CLAIM_SCOPES=name:profile,family_name:profile,given_name:profile,email:email,https%3A%2F%2Fmy-company.com%2Fclaims%2Froles:roles \
    werther

For more details about claims naming see OpenID Connect Core 1.0.

NB There are cases when we need to create several roles with the same name in LDAP. For example, when we want to configure multiple applications or several environments for the same application.

dc=com
|-- dc=example
    |-- ou=AppRoles
        |-- ou=Test
            |-- ou=App1
                |-- cn=test_app1_role1 (objectClass="group", description="role1")
                |-- cn=test_app1_role2 (objectClass="group", description="role2")
            |-- ou=App2
                |-- cn=test_app2_role1 (objectClass="group",description-"role1")
                |-- cn=test_app2_role2 (objectClass="group",description-"role2")
        |-- ou=Dev
            |-- ou=App1
                |-- cn=dev_app1_role1 (objectClass="group", description="role1")
                |-- cn=dev_app1_role3 (objectClass="group", description="role3")
            |-- ou=App2
                |-- cn=dev_app2_role1 (objectClass="group",description-"role1")
                |-- cn=dev_app2_role4 (objectClass="group",description-"role4")

Active Directory requires unique CNs in a domain. But in Active Directory creating groups with the same CN in different OUs is difficult. Because of it, Werther uses a LDAP attribute as a role's name instead of CN. A name of a LDAP attribute is specified using the environment variable WERTHER_LDAP_ROLE_ATTR, and has the default value description.

In the above example, Werther returns a response that contains the next roles:

  • when the environment variable WERTHER_LDAP_ROLE_DN equals to ou=Test,ou=AppRoles,dc=example,dc=com:
    {
        "https://github.com/i-core/werther/claims/roles": {
            "App1": ["role1", "role2"],
            "App2": ["role1", "role2"]
        }
    }
  • when the environment variable WERTHER_LDAP_ROLE_DN equals to ou=Dev,ou=AppRoles,dc=example,dc=com:
    {
        "https://github.com/i-core/werther/claims/roles": {
            "App1": ["role1", "role3"],
            "App2": ["role1", "role4"]
        }
    }

UI customization

Werther uses the Go templates to render UI pages. To customize the UI you should create a directory that contains UI pages' templates. After that you should set the directory path to the environment variable WERTHER_WEB_DIR.

Custom login page

A login page's template must be a Go template. The template has access to data conforming the next JSON-schema:

type: object
properties:
  - WebBasePath:
      description: The base path of the login page
      type: string
  - LangPrefs:
      description: The user language preferences (the parsed value of the header Accept-Language)
      type: array
      items:
        type: object
        properties:
          - Lang:
              description: The language canonical name.
              type: string
          - Weight:
              description: The language weight.
              type: number
        required:
          - Lang
          - Weight
  - Data:
      type: object
      properties:
        - CSRFToken:
            description: A CSRF token.
            type: string
        - Challenge:
            description: A login challenge ID.
            type: string
        - LoginURL:
            description: An endpoint that finishes the login process.
            type: string
        - IsInvalidCredentials:
            description: Specifies that a user types an invalid username or password.
            type: boolean
        - IsInternalError:
            description: Specifies that an internal server error happens when finishing the login process.
            type: boolean
      required:
        - CSRFToken
        - Challenge
        - LoginURL
        - IsInvalidCredentials
        - IsInternalError
required:
  - WebBasePath
  - LangPrefs
  - Data

When a login page's template contains static resources (like styles, scripts, and images) they must be placed in a subdirectory called static.

For a full example of a login page's template see source code.

Custom login page (old format)

The old template format is also supported but it will be removed in the future major release.

A login page's template should contains blocks title, style, script, content. Each block has access to data conforming the next JSON-schema:

type: object
properties:
  - CSRFToken:
    description: A CSRF token.
    type: string
  - Challenge:
    description: A login challenge ID.
    type: string
  - LoginURL:
    description: An endpoint that finishes the login process.
    type: string
  - IsInvalidCredentials:
    description: Specifies that a user types an invalid username or password.
    type: boolean
  - IsInternalError:
    description: Specifies that an internal server error happens when finishing the login process.
    type: boolean
required:
  - CSRFToken
  - Challenge
  - LoginURL
  - IsInvalidCredentials
  - IsInternalError

When a login page's template contains static resources (like styles, scripts, and images) they must be placed in a subdirectory called static.

For a full example of a login page's template see source code.

Example

  1. Create file ldap.ldif:

    dn: uid=kolya_gerasyimov,ou=Users,dc=example,dc=com
    objectClass: inetOrgPerson
    cn: Kolya Gerasyimov
    sn: Gerasyimov
    uid: kolya_gerasyimov
    userPassword: 123
    mail: [email protected]
    ou: Users
    
    dn: ou=AppRoles,dc=example,dc=com
    objectClass: organizationalunit
    ou: AppRoles
    description: AppRoles
    
    dn: ou=App1,ou=AppRoles,dc=example,dc=com
    objectClass: organizationalunit
    ou: App1
    description: App1
    
    dn: cn=traveler,ou=App1,ou=AppRoles,dc=example,dc=com
    objectClass: groupofnames
    cn: traveler
    description: traveler
    member: uid=kolya_gerasyimov,ou=Users,dc=example,dc=com
    
  2. Create file docker-compose.yml:

    version: "3"
    services:
        hydra-client:
            image: oryd/hydra:v1.0.0-rc.12
            environment:
                HYDRA_ADMIN_URL: http://hydra:4445
            command:
                - clients
                - create
                - --skip-tls-verify
                - --id
                - test-client
                - --secret
                - test-secret
                - --response-types
                - id_token,token,"id_token token"
                - --grant-types
                - implicit
                - --scope
                - openid,profile,email,roles
                - --callbacks
                - http://localhost:3000
                - --post-logout-callbacks
                - http://localhost:3000/post-logout-callback
            networks:
                - hydra-net
            deploy:
                restart_policy:
                    condition: none
            depends_on:
                - hydra
            healthcheck:
                test: ["CMD", "curl", "-f", "http://hydra:4445"]
                interval: 10s
                timeout: 10s
                retries: 10
        hydra:
            image: oryd/hydra:v1.0.0-rc.12
            environment:
                URLS_SELF_ISSUER: http://localhost:4444
                URLS_SELF_PUBLIC: http://localhost:4444
                URLS_LOGIN: http://localhost:8080/auth/login
                URLS_CONSENT: http://localhost:8080/auth/consent
                URLS_LOGOUT: http://localhost:8080/auth/logout
                WEBFINGER_OIDC_DISCOVERY_SUPPORTED_SCOPES: profile,email,phone,roles
                WEBFINGER_OIDC_DISCOVERY_SUPPORTED_CLAIMS: name,family_name,given_name,nickname,email,phone_number,https://github.com/i-core/werther/claims/roles
                DSN: memory
            command: serve all --dangerous-force-http
            networks:
                - hydra-net
            ports:
                - "4444:4444"
                - "4445:4445"
            deploy:
                restart_policy:
                    condition: on-failure
            depends_on:
                - werther
        werther:
            image: icoreru/werther:v1.1.1
            environment:
                WERTHER_IDENTP_HYDRA_URL: http://hydra:4445
                WERTHER_LDAP_ENDPOINTS: ldap:389
                WERTHER_LDAP_BINDDN: cn=admin,dc=example,dc=com
                WERTHER_LDAP_BINDPW: password
                WERTHER_LDAP_BASEDN: "dc=example,dc=com"
                WERTHER_LDAP_ROLE_BASEDN: "ou=AppRoles,dc=example,dc=com"
            networks:
                - hydra-net
            ports:
                - "8080:8080"
            deploy:
                restart_policy:
                    condition: on-failure
            depends_on:
                - ldap
        ldap:
            image: pgarrett/ldap-alpine
            volumes:
                - "./ldap.ldif:/ldif/ldap.ldif"
            networks:
                - hydra-net
            ports:
                - "389:389"
            deploy:
                restart_policy:
                    condition: on-failure
    networks:
        hydra-net:
  3. Run the command:

    docker stack deploy -c docker-compose.yml auth
  4. Open the browser with http://localhost:4444/oauth2/auth?client_id=test-client&response_type=token&scope=openid%20profile%20email%20roles&state=12345678.

Resources

Footnotes

  1. Werther is named after robot Werther from Guest from the Future.

Contributing

Thanks for your interest in contributing to this project. Get started with our Contributing Guide.

License

The code in this project is licensed under MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].