ad2image provides an easy-to-use, minimalistic HTTP API to retrieve user photos from an Active Directory / Microsoft Exchange environment. It also provides fallback photos using avatar-generator if a user has no photo stored.
Behind the curtains, by default a 64x64 pixel thumbnail photo is retrieved from Active Directory (Attribute
thumbnailPhoto). Higher resolution photos can also be requested, those will be fetched by using
the Exchange EWS REST API.
ad2image can be integrated in your Spring Boot application by using the provided starter
ad2image-spring-boot-starter.
If you want to deploy ad2image as a standalone application, you can use
the provided container image or Helm chart.
ad2image was initially created as mucatar internally at it@M. It is used by many of our in-house projects to provide user photos for a richer user experience. For example, it can be very easily used as photo provider for Vuetify's Avatar component.
This project is built with technologies we use in our projects:
- Java
- Spring Boot
mvn clean installFor development, an Active Directory / Exchange environment is not needed. It is mocked by an embedded LDAP server and WireMock (for the EWS API).
OpenAPI v3 documentation is provided and can be retrieved via Swagger UI (<your-instance>/swagger-ui/index.html).
GET /avatar?uid=john.doe[&m=identicon|404|fallbackIdenticon|...][&size=64]
Possible modes (m):
404: 404 Response, if the user has no photo stored in AD/Exchangeidenticon: renders an Identicon, if the user has no photo stored in AD/ExchangefallbackIdenticon: identical toidenticon, but also responds with an Identicon if the user itself does not exist in AD/Exchangegeneric: renders an generic placeholder icon, if the user has no photo stored in AD/ExchangefallbackGeneric: default - identical togeneric, but also responds with an generic placeholder icon if the user itself does not exist in AD/ExchangegenericDark: renders a generic placeholder icon with white foreground (for dark mode applications), if the user has no photo stored in AD/ExchangefallbackGenericDark: identical togenericDark, but also responds with a generic placeholder icon with white foreground if the user itself does not exist in AD/Exchangetriangle: renders an randomly generated Avatar based on triangles, if the user has no photo stored in AD/ExchangefallbackTriangle: identical totriangle, but also responds correspondingly if the user itself does not exist in AD/Exchangesquare: renders an randomly generated Avatar based on squares, if the user has no photo stored in AD/ExchangefallbackSquare: identical tosquare, but also responds correspondingly if the user itself does not exist in AD/Exchangegithub: renders an randomly generated Avatar based Github avatar style, if the user has no photo stored in AD/ExchangefallbackGithub: identical togithub, but also responds correspondingly if the user itself does not exist in AD/Exchangeinitials: renders a colored square avatar with the user's initials (first letter of given name + first letter of surname), derived from the user's ADgivenNameandsnattributes. The background color is deterministically derived from the user's uid. If no name is stored, a plain colored rectangle is rendered. Returns 404 if the user does not exist in AD. The background colors ininitialsmode (implemented in InitialsAvatarGenerator.java) are chosen using an HSL strategy (60% saturation and ~45% lightness) to provide sufficient contrast with the white initials text for accessibility.
Possible resolutions (size): between 1 and 2048 pixels
ad2image provides an API endpoint that mimics the Gravatar API but internally resolves the user photos from your Active Directory / Exchange environment:
GET /gravatar/<sha256-hex-hash-of-lowercase-trimmed-mail-address>?[d=identicon/404]&s=200
When the Gravatar compatability endpoint is activated, ad2image retrieves all users from Active Directory on startup to compute an in-memory lookup table that contains the SHA256-hashed mail addresses. ad2image also can periodically update this lookup table during runtime. See Configuration for more details on how to configure this endpoint for your environment.
This endpoint also only supports a subset of the Gravatar API features:
- Default image (
dquery param):identicon,404,mp(mystery person), andinitialsare supported; other values fall back to the configured gravatar default mode - Size: can be requested between 1 and 2048px
- Force Default (
f): not supported, will be ignored - Rating (
r): not supported, will be ignored
You can use the provided official Docker image ghcr.io/it-at-m/ad2image to run ad2image as a standalone application.
docker run -d -p 8080:8080 --name ad2image ghcr.io/it-at-m/ad2image:1.1.1To connect to your Exchange/EWS environment, some environment variables must be set, see Configuration for a full list.
By default, ad2image uses a server-side cache (
see default_ehcache.xml). You can provide your own ehcache.xml
if you want to change the cache configuration (e.g. decrease the TTL).
- Create your custom
ehcache.xmland mount it as a volume for the container, for example with Docker--mount:
docker run --mount type=bind,source=/home/user/my-ehcache.xml,target=/cacheconfig/my-ehcache.xml,readonly [...]
- Set the container environment variable
SPRING_CACHE_JCACHE_CONFIGto point to the customehcache.xml, for example:
SPRING_CACHE_JCACHE_CONFIG=file:/cacheconfig/my-ehcache.xml
If you want to deploy ad2image on a Kubernetes cluster, you can use the provided Helm chart.
ad2image can be integrated in a existing Spring Boot application by adding the ad2image-spring-boot-starter
dependency, e.g. for Maven:
<dependency>
<groupId>de.muenchen.oss.ad2image</groupId>
<artifactId>ad2image-spring-boot-starter</artifactId>
<version>1.1.1</version><!-- see GitHub Release for latest version -->
</dependency>To configure ad2image, add the corresponding de.muenchen.oss.ad2image.* properties to your application.properties/
application.yml. For a full list of possible configuration properties see Configuration.
ad2image can be configured via Spring environment abstraction.
| Environment variable | System/Spring property | Description | Default value | Required |
|---|---|---|---|---|
DE_MUENCHEN_OSS_AD2IMAGE_ENABLED |
de.muenchen.oss.ad2image.enabled |
can be used to disable ad2image auto configuration (if integrated in your own application) | - | no |
DE_MUENCHEN_OSS_AD2IMAGE_DEFAULT_MODE |
de.muenchen.oss.ad2image.default-mode |
Default mode (m) if user provides none. |
"M_FALLBACK_GENERIC" (fallbackGeneric) |
yes |
DE_MUENCHEN_OSS_AD2IMAGE_AD_URL |
de.muenchen.oss.ad2image.ad.url |
Connection URL for AD server, for example 'ldaps://example.com:636'. | - | yes |
DE_MUENCHEN_OSS_AD2IMAGE_AD_USER_DN |
de.muenchen.oss.ad2image.ad.user-dn |
Bind User-DN for AD authentication | - | yes |
DE_MUENCHEN_OSS_AD2IMAGE_AD_PASSWORD |
de.muenchen.oss.ad2image.ad.password |
Password for AD authentication | - | yes |
DE_MUENCHEN_OSS_AD2IMAGE_AD_USER_SEARCH_BASE |
de.muenchen.oss.ad2image.ad.user-search-base |
User Search Base for user lookup, for example 'OU=Users,DC=mycompany,DC=com'. | - | yes |
DE_MUENCHEN_OSS_AD2IMAGE_AD_USER_SEARCH_FILTER |
de.muenchen.oss.ad2image.ad.user-search-filter |
User Search filter, {uid} will be replaced with the requested user uid. |
(&(objectClass=organizationalPerson)(cn={uid})) |
yes |
DE_MUENCHEN_OSS_AD2IMAGE_AD_SN_ATTRIBUTE |
de.muenchen.oss.ad2image.ad.sn-attribute |
LDAP attribute name for the user's surname, used to build initials avatars. | sn |
no |
DE_MUENCHEN_OSS_AD2IMAGE_AD_GIVEN_NAME_ATTRIBUTE |
de.muenchen.oss.ad2image.ad.given-name-attribute |
LDAP attribute name for the user's given name, used to build initials avatars. | givenName |
no |
DE_MUENCHEN_OSS_AD2IMAGE_EWS_EWS_SERVICE_URL |
de.muenchen.oss.ad2image.ews.ews-service-url |
EWS service URL, e.g. https://example.com/ews/Exchange.asmx. |
- | yes |
DE_MUENCHEN_OSS_AD2IMAGE_EWS_USERNAME |
de.muenchen.oss.ad2image.ews.username |
Username for EWS Basic Authentication. | - | yes |
DE_MUENCHEN_OSS_AD2IMAGE_EWS_PASSWORD |
de.muenchen.oss.ad2image.ews.password |
Password for EWS Basic Authentication. | - | yes |
DE_MUENCHEN_OSS_AD2IMAGE_GRAVATAR_ENABLED |
de.muenchen.oss.ad2image.gravatar.enabled |
Enables/disables the Gravatar compatability endpoint. | false |
no |
DE_MUENCHEN_OSS_AD2IMAGE_GRAVATAR_HASH_CACHE_REFRESH_CRON |
de.muenchen.oss.ad2image.gravatar.hash-cache-refresh-cron |
Spring "cron" expression for periodic refresh of the SHA256 email address hashes, '-' to disable. | - |
no |
DE_MUENCHEN_OSS_AD2IMAGE_GRAVATAR_MAP_POPULATION_FILTER |
de.muenchen.oss.ad2image.gravatar.map-population-filter |
LDAP search filter for users which should be included in generation of SHA256-hashed email addresses. | (&(objectClass=organizationalPerson)(mail=*)) |
no |
DE_MUENCHEN_OSS_AD2IMAGE_GRAVATAR_PAGE_SIZE |
de.muenchen.oss.ad2image.gravatar.page-size |
page size for retrieval of users during map population. | 500 |
no |
DE_MUENCHEN_OSS_AD2IMAGE_GRAVATAR_DEFAULT_MODE |
de.muenchen.oss.ad2image.gravatar.default-mode |
Default mode for Gravatar API when the requested d= parameter is unsupported or missing. Independent from the main avatar API's default mode setting. |
M_FALLBACK_GENERIC |
no |
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please open an issue with the tag "enhancement", fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Open an issue with the tag "enhancement"
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
We use itm-java-codeformat, so please make sure to apply the correct code format for your contributions.
Distributed under the MIT License. See LICENSE file for more information.
it@M - opensource@muenchen.de