diff --git a/src/Entities/Bases/AbstractProvider.php b/src/Entities/Bases/AbstractProvider.php
index 9e63abde92dc28fc928e623ea3be29f2794de2fb..c4b66b672dafc44b29e24f04faafb5bef1356afa 100755
--- a/src/Entities/Bases/AbstractProvider.php
+++ b/src/Entities/Bases/AbstractProvider.php
@@ -18,23 +18,28 @@ abstract class AbstractProvider implements ProviderInterface
         $this->entityId = $this->resolveEntityId();
     }
 
-    protected function resolveOptionallyLocalizedString(string $key, string $locale = 'en'): ?string
-    {
-        if (!isset($this->metadata[$key])) {
+    protected function resolveOptionallyLocalizedString(
+        string $key,
+        string $locale = self::DEFAULT_LOCALE,
+        array $metadataOverride = null
+    ): ?string {
+        $metadata = $metadataOverride ?? $this->metadata;
+
+        if (!isset($metadata[$key])) {
             return null;
         }
 
         // Check for non-localized version.
-        if (is_string($this->metadata[$key])) {
-            return $this->metadata[$key];
+        if (is_string($metadata[$key])) {
+            return $metadata[$key];
         }
 
         if (
-            is_array($this->metadata[$key]) &&
-            !empty($this->metadata[$key][$locale]) &&
-            is_string($this->metadata[$key][$locale])
+            is_array($metadata[$key]) &&
+            !empty($metadata[$key][$locale]) &&
+            is_string($metadata[$key][$locale])
         ) {
-            return $this->metadata[$key][$locale];
+            return $metadata[$key][$locale];
         }
 
         return null;
@@ -50,8 +55,9 @@ abstract class AbstractProvider implements ProviderInterface
         return $this->entityId;
     }
 
-    abstract public function getName(string $locale = 'en'): ?string;
-    abstract public function getDescription(string $locale = 'en'): ?string;
+    abstract public function getName(string $locale = self::DEFAULT_LOCALE): ?string;
+    abstract public function getDescription(string $locale = self::DEFAULT_LOCALE): ?string;
     abstract protected function resolveEntityId(): string;
     abstract public function getProtocol(): AuthenticationProtocolInterface;
+    abstract protected function getProviderDescription(): string;
 }
diff --git a/src/Entities/Interfaces/ProviderInterface.php b/src/Entities/Interfaces/ProviderInterface.php
index c82a1792698873b1ba3e295addba031708832ca4..a5957a51fc49a2258d3ae76effb2a849d1dcc014 100755
--- a/src/Entities/Interfaces/ProviderInterface.php
+++ b/src/Entities/Interfaces/ProviderInterface.php
@@ -9,9 +9,11 @@ use SimpleSAML\Module\accounting\Entities\Bases\AbstractPayload;
 
 interface ProviderInterface
 {
+    public const DEFAULT_LOCALE = 'en';
+
     public function getMetadata(): array;
-    public function getName(string $locale = 'en'): ?string;
+    public function getName(string $locale = self::DEFAULT_LOCALE): ?string;
     public function getEntityId(): string;
-    public function getDescription(string $locale = 'en'): ?string;
+    public function getDescription(string $locale = self::DEFAULT_LOCALE): ?string;
     public function getProtocol(): AuthenticationProtocolInterface;
 }
diff --git a/src/Entities/Providers/Bases/AbstractSaml2Provider.php b/src/Entities/Providers/Bases/AbstractSaml2Provider.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a5fd987ce73f561c7a66451fe6233eda59e9a38
--- /dev/null
+++ b/src/Entities/Providers/Bases/AbstractSaml2Provider.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace SimpleSAML\Module\accounting\Entities\Providers\Bases;
+
+use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider;
+use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
+use SimpleSAML\Module\accounting\Exceptions\MetadataException;
+use SimpleSAML\Module\accounting\Entities\Authentication;
+
+abstract class AbstractSaml2Provider extends AbstractProvider
+{
+    public const METADATA_KEY_ENTITY_ID = 'entityid';
+    public const METADATA_KEY_NAME = 'name';
+    public const METADATA_KEY_DESCRIPTION = 'description';
+    public const METADATA_KEY_UI_INFO = 'UIInfo';
+    public const METADATA_KEY_UI_INFO_DESCRIPTION = 'Description';
+    public const METADATA_KEY_UI_INFO_DISPLAY_NAME = 'DisplayName';
+
+    protected function getEntityInfoString(string $key, string $locale = self::DEFAULT_LOCALE): ?string
+    {
+        return $this->resolveOptionallyLocalizedString($key, $locale);
+    }
+
+    protected function getEntityUiInfoString(string $key, string $locale = self::DEFAULT_LOCALE): ?string
+    {
+        if (
+            isset($this->metadata[self::METADATA_KEY_UI_INFO]) &&
+            is_array($this->metadata[self::METADATA_KEY_UI_INFO])
+        ) {
+            return $this->resolveOptionallyLocalizedString(
+                $key,
+                $locale,
+                $this->metadata[self::METADATA_KEY_UI_INFO]
+            );
+        }
+
+        return null;
+    }
+
+    public function getName(string $locale = self::DEFAULT_LOCALE): ?string
+    {
+        return $this->getEntityInfoString(self::METADATA_KEY_NAME, $locale) ??
+            $this->getEntityUiInfoString(self::METADATA_KEY_UI_INFO_DISPLAY_NAME, $locale);
+    }
+
+    public function getDescription(string $locale = self::DEFAULT_LOCALE): ?string
+    {
+        return $this->getEntityInfoString(self::METADATA_KEY_DESCRIPTION, $locale) ??
+            $this->getEntityUiInfoString(self::METADATA_KEY_UI_INFO_DESCRIPTION, $locale);
+    }
+
+    /**
+     * @throws MetadataException
+     */
+    protected function resolveEntityId(): string
+    {
+        if (empty($entityId = $this->getEntityInfoString(self::METADATA_KEY_ENTITY_ID))) {
+            $message = sprintf('Provider metadata does not contain entity ID (%s).', $this->getProviderDescription());
+            throw new MetadataException($message);
+        }
+
+        return $entityId;
+    }
+
+    public function getProtocol(): AuthenticationProtocolInterface
+    {
+        return new Authentication\Protocol\Saml2();
+    }
+}
diff --git a/src/Entities/Providers/Identity/Oidc.php b/src/Entities/Providers/Identity/Oidc.php
index c662f78753be98476d0c03d8086fb94a0dafa24b..9bc3784b9fd14184f5c9e9f70f1e7c0c34411f3a 100755
--- a/src/Entities/Providers/Identity/Oidc.php
+++ b/src/Entities/Providers/Identity/Oidc.php
@@ -43,4 +43,9 @@ class Oidc extends AbstractProvider implements IdentityProviderInterface
     {
         return new Authentication\Protocol\Oidc();
     }
+
+    protected function getProviderDescription(): string
+    {
+        return $this->getProtocol()->getDesignation() . ' OpenID Provider';
+    }
 }
diff --git a/src/Entities/Providers/Identity/Saml2.php b/src/Entities/Providers/Identity/Saml2.php
index 04768636840af510618c96d26587f396b283afe4..8bef30d9a6a930bac920b202f27e8d3e90a13afa 100755
--- a/src/Entities/Providers/Identity/Saml2.php
+++ b/src/Entities/Providers/Identity/Saml2.php
@@ -5,44 +5,15 @@ declare(strict_types=1);
 namespace SimpleSAML\Module\accounting\Entities\Providers\Identity;
 
 use SimpleSAML\Module\accounting\Entities\Authentication;
-use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider;
 use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
 use SimpleSAML\Module\accounting\Entities\Interfaces\IdentityProviderInterface;
+use SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider;
 use SimpleSAML\Module\accounting\Exceptions\MetadataException;
 
-class Saml2 extends AbstractProvider implements IdentityProviderInterface
+class Saml2 extends AbstractSaml2Provider implements IdentityProviderInterface
 {
-    public const METADATA_KEY_NAME = 'name';
-    public const METADATA_KEY_ENTITY_ID = 'entityid';
-    public const METADATA_KEY_DESCRIPTION = 'description';
-
-    public function getName(string $locale = 'en'): ?string
-    {
-        return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_NAME, $locale);
-    }
-
-    public function getDescription(string $locale = 'en'): ?string
-    {
-        return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_DESCRIPTION, $locale);
-    }
-
-    /**
-     * @throws MetadataException
-     */
-    protected function resolveEntityId(): string
-    {
-        if (
-            !empty($this->metadata[self::METADATA_KEY_ENTITY_ID]) &&
-            is_string($this->metadata[self::METADATA_KEY_ENTITY_ID])
-        ) {
-            return $this->metadata[self::METADATA_KEY_ENTITY_ID];
-        }
-
-        throw new MetadataException('Identity provider metadata does not contain entity ID.');
-    }
-
-    public function getProtocol(): AuthenticationProtocolInterface
+    protected function getProviderDescription(): string
     {
-        return new Authentication\Protocol\Saml2();
+        return $this->getProtocol()->getDesignation() . ' Identity Provider';
     }
 }
diff --git a/src/Entities/Providers/Service/Oidc.php b/src/Entities/Providers/Service/Oidc.php
index 5f5ff82477128169db5708b40932172d79b54a6d..c683718f5caddb8edd6018368c76ddbcb504b2bb 100755
--- a/src/Entities/Providers/Service/Oidc.php
+++ b/src/Entities/Providers/Service/Oidc.php
@@ -45,4 +45,9 @@ class Oidc extends AbstractProvider implements ServiceProviderInterface
     {
         return new Authentication\Protocol\Oidc();
     }
+
+    protected function getProviderDescription(): string
+    {
+        return $this->getProtocol()->getDesignation() . ' Relying Party';
+    }
 }
diff --git a/src/Entities/Providers/Service/Saml2.php b/src/Entities/Providers/Service/Saml2.php
index d0dfd4ac065c2b22a7f3dcdcf82c14096981f40d..deeb30727e3c05b0446c315b726a73923321c9c1 100755
--- a/src/Entities/Providers/Service/Saml2.php
+++ b/src/Entities/Providers/Service/Saml2.php
@@ -4,45 +4,13 @@ declare(strict_types=1);
 
 namespace SimpleSAML\Module\accounting\Entities\Providers\Service;
 
-use SimpleSAML\Module\accounting\Entities\Authentication;
-use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider;
-use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface;
 use SimpleSAML\Module\accounting\Entities\Interfaces\ServiceProviderInterface;
-use SimpleSAML\Module\accounting\Exceptions\MetadataException;
+use SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider;
 
-class Saml2 extends AbstractProvider implements ServiceProviderInterface
+class Saml2 extends AbstractSaml2Provider implements ServiceProviderInterface
 {
-    public const METADATA_KEY_ENTITY_ID = 'entityid';
-    public const METADATA_KEY_NAME = 'name';
-    public const METADATA_KEY_DESCRIPTION = 'description';
-
-    public function getName(string $locale = 'en'): ?string
-    {
-        return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_NAME, $locale);
-    }
-
-    public function getDescription(string $locale = 'en'): ?string
-    {
-        return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_DESCRIPTION, $locale);
-    }
-
-    /**
-     * @throws MetadataException
-     */
-    protected function resolveEntityId(): string
-    {
-        if (
-            !empty($this->metadata[self::METADATA_KEY_ENTITY_ID]) &&
-            is_string($this->metadata[self::METADATA_KEY_ENTITY_ID])
-        ) {
-            return $this->metadata[self::METADATA_KEY_ENTITY_ID];
-        }
-
-        throw new MetadataException('Service provider metadata does not contain entity ID.');
-    }
-
-    public function getProtocol(): AuthenticationProtocolInterface
+    protected function getProviderDescription(): string
     {
-        return new Authentication\Protocol\Saml2();
+        return $this->getProtocol()->getDesignation() . ' Service Provider';
     }
 }
diff --git a/tests/src/Entities/Bases/AbstractProviderTest.php b/tests/src/Entities/Bases/AbstractProviderTest.php
index e8d8a2743b4492f6242c9ae8aa5b162bc8cead90..e85837943cde85b720ddbd8a28fb0048beadbb24 100755
--- a/tests/src/Entities/Bases/AbstractProviderTest.php
+++ b/tests/src/Entities/Bases/AbstractProviderTest.php
@@ -112,6 +112,11 @@ class AbstractProviderTest extends TestCase
                     }
                 };
             }
+
+            protected function getProviderDescription(): string
+            {
+                return 'provider description';
+            }
         };
     }
 }
diff --git a/tests/src/Entities/Providers/Identity/Saml2Test.php b/tests/src/Entities/Providers/Identity/Saml2Test.php
index 7c995952a1fee1d1a238a78853682c393d655c6f..5c4db09f39ab25ac6fabe0066dc9d6aa76e15e17 100755
--- a/tests/src/Entities/Providers/Identity/Saml2Test.php
+++ b/tests/src/Entities/Providers/Identity/Saml2Test.php
@@ -12,6 +12,8 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays;
 /**
  * @covers \SimpleSAML\Module\accounting\Entities\Providers\Identity\Saml2
  * @uses \SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider
+ * @uses \SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider
+ * @uses \SimpleSAML\Module\accounting\Entities\Authentication\Protocol\Saml2
  */
 class Saml2Test extends TestCase
 {
diff --git a/tests/src/Entities/Providers/Service/Saml2Test.php b/tests/src/Entities/Providers/Service/Saml2Test.php
index c4475d7089d65d70742a6b2b14d65b0860f72316..225c92ab25da2ff79911036270f30ce651c88f26 100755
--- a/tests/src/Entities/Providers/Service/Saml2Test.php
+++ b/tests/src/Entities/Providers/Service/Saml2Test.php
@@ -9,6 +9,8 @@ use SimpleSAML\Module\accounting\Exceptions\MetadataException;
 /**
  * @covers \SimpleSAML\Module\accounting\Entities\Providers\Service\Saml2
  * @uses \SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider
+ * @uses \SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider
+ * @uses \SimpleSAML\Module\accounting\Entities\Authentication\Protocol\Saml2
  */
 class Saml2Test extends TestCase
 {
diff --git a/tests/src/Helpers/ProviderResolverTest.php b/tests/src/Helpers/ProviderResolverTest.php
index 3661701b49175bb33f0e00568a2dbbd82b0fe60c..1e7f3fe5e7bae7ce2df95c6355f2854496ab381f 100755
--- a/tests/src/Helpers/ProviderResolverTest.php
+++ b/tests/src/Helpers/ProviderResolverTest.php
@@ -21,6 +21,8 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays;
  * @uses \SimpleSAML\Module\accounting\Entities\Providers\Identity\Oidc
  * @uses \SimpleSAML\Module\accounting\Entities\Providers\Service\Saml2
  * @uses \SimpleSAML\Module\accounting\Entities\Providers\Service\Oidc
+ * @uses \SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider
+ * @uses \SimpleSAML\Module\accounting\Entities\Authentication\Protocol\Saml2
  */
 class ProviderResolverTest extends TestCase
 {