Skip to content

Commit

Permalink
feat: reworked options and injectables
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Structure and options
  • Loading branch information
simonecorsi committed Nov 22, 2022
1 parent bff0472 commit 3ecc9cb
Show file tree
Hide file tree
Showing 11 changed files with 393 additions and 332 deletions.
Empty file added ldap.js
Empty file.
95 changes: 61 additions & 34 deletions packages/ldap-auth-backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
</p>
<h1 align="center">@immobiliarelabs/backstage-plugin-ldap-auth-backend</h1>

![npm (scoped)](https://img.shields.io/npm/v/@immobiliarelabs/backstage-plugin-ldap-auth-backend?style=flat-square)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier?style=flat-square)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
![license](https://img.shields.io/github/license/immobiliare/backstage-plugin-ldap-auth?style=flat-square)
![npm (scoped)](https://img.shields.io/npm/v/@immobiliarelabs/backstage-plugin-ldap-auth-backend?style=flat-square)

> Customizable Authentication backend provider for LDAP servers for your [Backstage](https://backstage.io/) deployment
> LDAP Authentication your [Backstage](https://backstage.io/) deployment
Works either on simple stand-alone process or scaled infrastracture spanning multiple deployments using the shared PostgreSQL instance that Backstage already uses!
This package is the Backend Provider to add LDAP authentication to your Backstage instance!

- Customizable: Authentication request format and marshaling of the response can be injected with custom ones;
- Works on simple stand-alone process or scaled infrastracture spanning multiple deployments using the shared PostgreSQL instance that Backstage already uses;

This plugin is not meant to be used alone but in pair with:

Expand All @@ -25,9 +28,10 @@ All the current LTS versions are supported.

- [Installation](#installation)
- [Configurations](#configurations)
- [Setup](#setup)
- [Connection Configuration](#connection-configuration)
- [Setup Backstage official LDAP plugin](#setup-backstage-official-ldap-plugin)
- [Add authentication backend](#add-authentication-backend)
- [Add the authentication backend plugin](#add-the-authentication-backend-plugin)
- [Custom configurations](#custom-configurations)
- [Add the login form](#add-the-login-form)
- [Powered Apps](#powered-apps)
- [Support & Contribute](#support--contribute)
Expand All @@ -54,36 +58,15 @@ $ yarn workspace app add @immobiliarelabs/backstage-plugin-ldap-auth

> This documentation assumes that you have already scaffolded your Backstage instance from the official `@backstage/create-app`, all files that we're going to customize here are the one already created by the CLI!
### Connection Configuration

> Adds connection configuration inside your backstage YAML config file, eg: `app-config.yaml`
This fields are all required
### Setup

| key | description |
| -------------------- | ---------------------------------------------------------------- |
| `url` | Array of ldap connection strings |
| `rejectUnauthorized` | Reject non HTTPS traffic, this also set secure cookies when true |
| `userDn` | User distinguished name directory location |
| `userSearchBase` | Userbase search location |
If you didn't have already, you need to configure Backstage's official LDAP plugin, that is needed to import and keep in syncs users your LDAP users.

```yml
auth:
environment: ENV_NAME
providers:
ldap:
ENV_NAME:
url:
- 'ldaps://123.123.123.123'
rejectUnauthorized: true
userDn: 'ou=usr,dc=ns,dc=frm'
userSearchBase: 'dc=ns,dc=frm'
```sh
# in your backstage repo
yarn add @backstage/plugin-catalog-backend-module-ldap
```

### Setup Backstage official LDAP plugin
If you didn't have already, we need to configure the official LDAP plugin to imports and keep in syncs users
> `packages/backend/src/plugins/catalog.ts`
```ts
Expand Down Expand Up @@ -120,9 +103,49 @@ export default async function createPlugin(
}
```

### Add authentication backend
### Connection Configuration

This assumes a basic usage: single process without custom auth function or user object customization and in-memory token storage
> Adds connection configuration inside your backstage YAML config file, eg: `app-config.yaml`
We use [`ldap-authentication`](https://github.com/shaozi/ldap-authentication) for authentication, you can find all the configurations at this [link], `ldapOpts` fields are options provided to lower level ldap client read more at [`ldapjs` ](https://github.com/ldapjs/node-ldapjs)

> Add in you You backstage configuration file
```yml
auth:
environment: { ENV_NAME } # eg: production|staging|review|develop
providers:
ldap:
# eg: production|staging|review|develop
{ ENV_NAME }:
cookies:
secure: false # https cookies or not
field: '' # default to "backstage-token"

ldapAuthentication:
# what is the user unique key in your ldap instance
usernameAttribute: 'uid'
# directory where to search user
# default search will be `[userSearchBase]=[username],[userSearchBase]`
userSearchBase: 'ou=users,dc=ns,dc=farm'

# User able to list other users, this is used
# to check incoming JWT if user are already part of the LDAP

# usually is [userSearchBase]=[username],[userSearchBase]
adminDn: uid={ADMIN_USERNAME},ou=users,dc=ns,dc=farm
adminPassword: ''

ldapOpts:
url:
- 'ldaps://172.16.0.154'
tlsOptions:
rejectUnauthorized: false
```
### Add the authentication backend plugin
This is for a basic usage: - single process - No custom auth or user object marshaling - in-memory sessions
For more uses cases you can see the [example folders](https://github.com/immobiliare/backstage-plugin-ldap-auth/examples/)
Expand All @@ -144,12 +167,16 @@ export default async function createPlugin(
discovery: env.discovery,
tokenManager: env.tokenManager,
providerFactories: {
ldap: ldap.create({}),
ldap: ldap.create(),
},
});
}
```

#### Custom configurations

If you need more fine control over LDAP Configuration you can provide custom `LdapAuthenticationOptions` and/or `LdapClientOptions` when initializing the provider, [example here](#add-authentication-backend).

### Add the login form

> More on this in the frontend plugin documentation [here](../ldap-auth/README.md)
Expand Down
50 changes: 50 additions & 0 deletions packages/ldap-auth-backend/src/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type {
BackstageSignInResult,
BackstageIdentityResponse,
LDAPUser,
} from './types';

import { ProfileInfo } from '@backstage/core-plugin-api';
import {
AuthHandler,
AuthResolverContext,
SignInResolver,
} from '@backstage/plugin-auth-backend';
import { parseJwtPayload } from './jwt';

export function prepareBackstageIdentityResponse(
result: BackstageSignInResult
): BackstageIdentityResponse {
const { sub, ent } = parseJwtPayload(result.token);

return {
...result,
identity: {
type: 'user',
userEntityRef: sub,
ownershipEntityRefs: ent ?? [],
},
};
}

export const defaultSigninResolver: SignInResolver<LDAPUser> = async (
{ result },
ctx: AuthResolverContext
): Promise<BackstageSignInResult> => {
const backstageIdentity: BackstageSignInResult =
await ctx.signInWithCatalogUser({
entityRef: result.uid as string,
});

return backstageIdentity;
};

export const defaultAuthHandler: AuthHandler<LDAPUser> = async (
{ uid },
ctx: AuthResolverContext
): Promise<{ profile: ProfileInfo }> => {
const backstageUserData = await ctx.findCatalogUser({
entityRef: uid as string,
});
return { profile: backstageUserData?.entity?.spec?.profile as ProfileInfo };
};
3 changes: 3 additions & 0 deletions packages/ldap-auth-backend/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ export const LDAP_CONNECT_FAIL = 'Failed to connect to LDAP server: ';

export const AUTH_MISSING_CREDENTIALS =
'AUTH_MISSING_CREDENTIALS: provide username and password or token';

export const AUTH_USER_NOT_FOUND =
'AUTH_USER_NOT_FOUND: Credential invalid or user doesnt exists';
195 changes: 0 additions & 195 deletions packages/ldap-auth-backend/src/helpers.ts

This file was deleted.

Loading

0 comments on commit 3ecc9cb

Please sign in to comment.