Getting started
1. Add the starter
<dependency>
<groupId>org.alexmond</groupId>
<artifactId>uniauth-spring-boot-starter</artifactId>
<version>4.1.0.3</version>
</dependency>
Nothing is enabled by default beyond the chain itself, because a starter that invented accounts would be worse than one that does nothing. Switch on at least one mechanism.
2. The smallest thing that works
uniauth:
enabled: true (1)
internal:
enabled: true
users:
- username: alice
password: "{noop}s3cret" (2)
roles: [ USER, ADMIN ]
| 1 | Required. The starter installs nothing until asked — it decides authorization, so being on the classpath is not consent. |
| 2 | {noop} is a DelegatingPasswordEncoder prefix meaning "stored in clear". Fine for a
first run; use {bcrypt}$2a$10$… anywhere else, and inject it from the environment
rather than committing it. |
Start the application and everything but the login page needs a session. Sign in at
/login.
3. Opening up some pages
uniauth:
public-paths:
- /
- /about
- /css/**
The starter already permits its own login page, the providers endpoint, /error and — when
the approval gate is on — the pending page. Anything else you want reachable without a
session goes here.
On Kubernetes, remember /actuator/**. Probes, Prometheus and Spring Boot Admin send
no credentials, so requiring authentication there rejects exactly the callers the endpoints
exist for.
|
4. Adding a directory
The LDAP jars are an optional dependency, so add them alongside the starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-ldap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
They are optional rather than transitive because carrying them is not free: their presence
activates Boot’s own LdapAutoConfiguration, which builds a context source for
ldap://localhost:389 and whose health indicator then reports DOWN. An application that
never wanted a directory would fail its readiness probe, and no uniauth.* property can
switch that off — the indicator is Boot’s, and it keys off the jar.
uniauth:
ldap:
enabled: true
url: ldap://directory.example.com:389/dc=example,dc=com
user-dn-patterns:
- uid={0},ou=people
group-search-base: ou=groups
manager-dn: cn=admin,dc=example,dc=com (1)
manager-password: ${LDAP_MANAGER_PASSWORD}
| 1 | Needed more often than it looks. A real directory is not world-readable — OpenLDAP’s
default ACL is by self read … by * none — and a denied search answers
no such object (32) rather than admitting the entry exists. Without a bind account the
user authenticates and then arrives with no groups, and the error points at a missing
entry that is plainly there. |
The internal store and LDAP share one username/password form. They are told apart by the
AuthenticationProvider chain, which is what lets a couple of local break-glass accounts
sit beside a directory.
5. Adding an OIDC provider
UniAuth does not re-declare OAuth2 configuration. Use Spring Boot’s own properties:
spring:
security:
oauth2:
client:
registration:
google:
client-id: ${GOOGLE_CLIENT_ID}
client-secret: ${GOOGLE_CLIENT_SECRET}
uniauth:
oauth2:
enabled: true # the default
That is the whole integration. The endpoints, scopes and user-name attribute come from
Boot’s CommonOAuth2Provider, keyed on the registration id; the chooser, the brand and the
OIDC-versus-plain-OAuth2 detection all follow. See Provider recipes for
the per-provider details that actually bite.
6. Adding SAML 2.0
SAML is an optional dependency, and it asks more of a build than the others — which is exactly why it is not transitive. Add both the starter and the Shibboleth repository:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security-saml2</artifactId>
</dependency>
<repositories>
<repository>
<id>shibboleth</id>
<url>https://build.shibboleth.net/maven/releases/</url>
</repository>
</repositories>
OpenSAML, which spring-security-saml2-service-provider needs, is not published to Maven
Central, so a Central-only build fails to resolve org.opensaml:*. Carrying it transitively
would push that repository onto every consumer of an authentication library, including the
ones that will never speak SAML and have nothing in the error message to tell them why.
It has to be Boot’s SAML starter, not spring-security-saml2-service-provider alone. Boot 4
moved SAML autoconfiguration into its own module; the Spring Security artifact gives you the
filters with no property binding, so spring.security.saml2.relyingparty.* is read by nobody,
no repository is built, the chooser lists nothing, and saml2Login never installs — silently,
because as far as the classpath is concerned nothing is missing.
uniauth:
saml:
enabled: true # the default
Registrations themselves come from spring.security.saml2.relyingparty.registration.*, exactly
as Boot documents them.
7. What to reach for next
-
The approval gate, if the answer to "may this person in" is not simply "yes, they authenticated".
-
Configuration, for the full property surface.
-
Examples, for a running demo of all four mechanisms at once.