SAML2
SAML2 authentication for PowerShell Universal.
PowerShell Universal can be configured to integrate with a SAML2 identity provider. This documentation provides the details for configuring PSU with such a system.

Identity Provider Settings

You will need to configure your identity provider for the PowerShell Universal application. You will need to setup an acceptable entity ID and map attributes. PowerShell Universal requires that the name attribute is mapped. The attribute name needs to be the following.
1
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
Copied!
You should map this to the user identity you wish to be used within PowerShell Universal.
Additional attributes can be mapped and will be available during role evaluation. You will find an example of configuring Shibboleth below.

Entity ID Settings

HTTPS is required for SAML2 authentication.
There are several basic settings you can configure in the PowerShell Universal admin console. To add SAML2 support, click Security \ Authentication. In the top right corner, you can select SAML2 from the drop down.
Once the SAML2 integration has been added, you can configure the basic settings for communicating with your identity provider. You will need at least the Entity ID and Identity Provider Entity ID configured.
Typically, these entity IDs are URLs configured within your identity provider.
Entity ID Settings
The service certificate is used for signing requests. It is not required. This can either be a path local to the PSU service or the distinguished name of a certificate installed in the Personal Computer Certificate store.

Additional Settings

In addition to the settings available within the admin console, you can also set the following within the authentication.ps1 config file.

ServiceCertificatePassword

If you are using a file path for your certificate and it requires a password, you can specify it via the -ServiceCertificatePassword of Set-PSUAuthenticationMethod. The value of this parameter is a SecureString. You can take advantage of the SecretManagement module to load secrets.
1
Set-PSUAuthenticationMethod `
2
-Type "Saml2" `
3
-EntityId "http://psu.ironman.local/sp" `
4
-IdentityProviderEntityId 'https://ironman.local/idp' `
5
-MetadataAddress 'https://idp.ironman.local/idp/shibboleth' `
6
-CallbackPath "https://localhost:5000/" `
7
-ServiceCertificate cert.pfx `
8
-ServiceCertificatePassword (Get-Secret -Name 'certPassword')
Copied!

Configure

The -Configure parameter is a script block that can be used to set additional settings not exposed by the Set-PSUAuthenticationMethod. The script block will be called when the provider is configured and will receive a single parameter that contains an object with the options for the SAML2 authentication.
The object is of the type Saml2Options. The sub object of SPOptions can be found here.
1
Set-PSUAuthenticationMethod `
2
-Type "Saml2" `
3
-EntityId "http://psu.ironman.local/sp" `
4
-IdentityProviderEntityId 'https://ironman.local/idp' `
5
-MetadataAddress 'https://idp.ironman.local/idp/shibboleth' `
6
-Configure {
7
$options = $args[0]
8
$options.SPOptions.DiscoveryServiceUrl = 'https://idp.ironman.local/discovery'
9
}
Copied!

Example: Shibboleth

This example shows how to configure Shibboleth for use with PowerShell Universal. It provides the very basic configuration and does not necessarily follow best practices.
This assumes that you have installed Shibboleth Identity Provider v4 with Active Directory integration.

ldap.properties

LDAP properties have been configured to authentication against the local domain using a Domain Administrator account. The LDAP URL has been configured and TLS has been disabled.
Below you will find the full example of the ldap.properties file.
1
# LDAP authentication (and possibly attribute resolver) configuration
2
# Note, this doesn't apply to the use of JAAS authentication via LDAP
3
4
## Authenticator strategy, either anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, adAuthenticator
5
idp.authn.LDAP.authenticator=adAuthenticator
6
7
## Connection properties ##
8
idp.authn.LDAP.ldapURL=ldap://ironman.local:389
9
idp.authn.LDAP.useStartTLS = false
10
# Time in milliseconds that connects will block
11
#idp.authn.LDAP.connectTimeout = PT3S
12
# Time in milliseconds to wait for responses
13
#idp.authn.LDAP.responseTimeout = PT3S
14
# Connection strategy to use when multiple URLs are supplied, either ACTIVE_PASSIVE, ROUND_ROBIN, RANDOM
15
#idp.authn.LDAP.connectionStrategy = ACTIVE_PASSIVE
16
17
## SSL configuration, either jvmTrust, certificateTrust, or keyStoreTrust
18
idp.authn.LDAP.sslConfig = jvmTrust
19
## If using certificateTrust above, set to the trusted certificate's path
20
idp.authn.LDAP.trustCertificates=%{idp.home}/credentials/ldap-server.crt
21
## If using keyStoreTrust above, set to the truststore path
22
idp.authn.LDAP.trustStore=%{idp.home}/credentials/ldap-server.truststore
23
24
## Return attributes during authentication
25
idp.authn.LDAP.returnAttributes=passwordExpirationTime,loginGraceRemaining,sn,mail
26
27
## DN resolution properties ##
28
29
# Search DN resolution, used by anonSearchAuthenticator, bindSearchAuthenticator
30
# for AD: CN=Users,DC=example,DC=org
31
idp.authn.LDAP.baseDN=CN=Users,DC=ironman, DC=local
32
idp.authn.LDAP.subtreeSearch = true
33
idp.authn.LDAP.userFilter=(sAMAccountName={user})
34
# bind search configuration
35
37
38
# Format DN resolution, used by directAuthenticator, adAuthenticator
39
# for AD use idp.authn.LDAP.dnFormat=%[email protected]
40
idp.authn.LDAP.dnFormat=%[email protected]
41
42
# pool passivator, either none, bind or anonymousBind
43
#idp.authn.LDAP.bindPoolPassivator = none
44
45
# LDAP attribute configuration, see attribute-resolver.xml
46
# Note, this likely won't apply to the use of legacy V2 resolver configurations
47
idp.attribute.resolver.LDAP.ldapURL=%{idp.authn.LDAP.ldapURL}
48
idp.attribute.resolver.LDAP.connectTimeout=%{idp.authn.LDAP.connectTimeout:PT3S}
49
idp.attribute.resolver.LDAP.responseTimeout=%{idp.authn.LDAP.responseTimeout:PT3S}
50
idp.attribute.resolver.LDAP.connectionStrategy=%{idp.authn.LDAP.connectionStrategy:ACTIVE_PASSIVE}
51
idp.attribute.resolver.LDAP.baseDN=%{idp.authn.LDAP.baseDN:undefined}
52
idp.attribute.resolver.LDAP.bindDN=%{idp.authn.LDAP.bindDN:undefined}
53
idp.attribute.resolver.LDAP.useStartTLS=%{idp.authn.LDAP.useStartTLS:true}
54
idp.attribute.resolver.LDAP.trustCertificates=%{idp.authn.LDAP.trustCertificates:undefined}
55
idp.attribute.resolver.LDAP.searchFilter=(sAMAccountName=$resolutionContext.principal)
56
57
# LDAP pool configuration, used for both authn and DN resolution
58
#idp.pool.LDAP.minSize = 3
59
#idp.pool.LDAP.maxSize = 10
60
#idp.pool.LDAP.validateOnCheckout = false
61
#idp.pool.LDAP.validatePeriodically = true
62
#idp.pool.LDAP.validatePeriod = PT5M
63
#idp.pool.LDAP.validateDN =
64
#idp.pool.LDAP.validateFilter = (objectClass=*)
65
#idp.pool.LDAP.prunePeriod = PT5M
66
#idp.pool.LDAP.idleTime = PT10M
67
#idp.pool.LDAP.blockWaitTime = PT3S
68
Copied!

relying-party.xml

The relying-party.xml file has been updated to enable open IdP. This means that any entity ID can communicate with the identity provider. You can also configure this to enforce specific entity IDs. The default configure has also been adjusted to use the SAML2.AttributeQuery bean.
1
<?xml version="1.0" encoding="UTF-8"?>
2
<beans xmlns="http://www.springframework.org/schema/beans"
3
xmlns:context="http://www.springframework.org/schema/context"
4
xmlns:util="http://www.springframework.org/schema/util"
5
xmlns:p="http://www.springframework.org/schema/p"
6
xmlns:c="http://www.springframework.org/schema/c"
7
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
9
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
10
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
11
12
default-init-method="initialize"
13
default-destroy-method="destroy">
14
15
<!--
16
Unverified RP configuration, defaults to no support for any profiles. Add <ref> elements to the list
17
to enable specific default profile settings (as below), or create new beans inline to override defaults.
18
19
"Unverified" typically means the IdP has no metadata, or equivalent way of assuring the identity and
20
legitimacy of a requesting system. To run an "open" IdP, you can enable profiles here.
21
-->
22
<bean id="shibboleth.UnverifiedRelyingParty" parent="RelyingParty">
23
<property name="profileConfigurations">
24
<list>
25
<bean parent="SAML2.SSO" p:encryptAssertions="false" />
26
</list>
27
</property>
28
</bean>
29
30
<!-- Default configuration, with default settings applied for all profiles. -->
31
<bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
32
<property name="profileConfigurations">
33
<list>
34
<!-- SAML 1.1 and SAML 2.0 AttributeQuery are disabled by default. -->
35
<!--
36
<bean parent="Shibboleth.SSO" />
37
<ref bean="SAML1.AttributeQuery" />
38
<ref bean="SAML1.ArtifactResolution" />
39
-->
40
<bean parent="SAML2.SSO" />
41
<ref bean="SAML2.ECP" />
42
<ref bean="SAML2.Logout" />
43
<ref bean="SAML2.AttributeQuery" />
44
<ref bean="SAML2.ArtifactResolution" />
45
<ref bean="Liberty.SSOS" />
46
</list>
47
</property>
48
</bean>
49
</beans>
50
Copied!

attribute-resolver.xml

The attribute-resolver.xml file has been updated to use the LDAPDirectory Data Connector. It loads the email address, given name, SN, and display name from Active Directory. It then maps the Principal Name, which will be the username of the user logging in, to the required claim type using an attribute encoder.
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
This file is an EXAMPLE configuration file containing some example attributes
4
based on some commonly used approaches when LDAP is the principal data source.
5
6
Not all attribute definitions or data connectors are demonstrated, but some
7
LDAP attributes common to Shibboleth deployments (and some not so common) are
8
included.
9
10
This example is in no way usable as a substitute for reading the documentation.
11
-->
12
<AttributeResolver
13
xmlns="urn:mace:shibboleth:2.0:resolver"
14
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
15
xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
16
17
<!-- ========================================== -->
18
<!-- Attribute Definitions -->
19
<!-- ========================================== -->
20
21
<!-- Simple attributes are exported directly from the LDAP connector. -->
22
23
<AttributeDefinition id="uid" xsi:type="PrincipalName" />
24
<AttributeDefinition id="username" xsi:type="PrincipalName">
25
<AttributeEncoder xsi:type="SAML2String" name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" friendlyName="displayName" encodeType="false" />
26
</AttributeDefinition>
27
28
<!-- ========================================== -->
29
<!-- Data Connectors -->
30
<!-- ========================================== -->
31
32
<!-- Example LDAP Connector -->
33
34
<DataConnector id="myLDAP" xsi:type="LDAPDirectory"
35
ldapURL="%{idp.attribute.resolver.LDAP.ldapURL}"
36
baseDN="%{idp.attribute.resolver.LDAP.baseDN}"
37
principal="%{idp.attribute.resolver.LDAP.bindDN}"
38
principalCredential="%{idp.attribute.resolver.LDAP.bindDNCredential}"
39
useStartTLS="%{idp.attribute.resolver.LDAP.useStartTLS:true}"
40
connectTimeout="%{idp.attribute.resolver.LDAP.connectTimeout}"
41
responseTimeout="%{idp.attribute.resolver.LDAP.responseTimeout}"
42
connectionStrategy="%{idp.attribute.resolver.LDAP.connectionStrategy}"
43
noResultIsError="true"
44
multipleResultsIsError="true"
45
excludeResolutionPhases="c14n/attribute"
46
exportAttributes="mail displayName sn givenName">
47
<FilterTemplate>
48
<![CDATA[
49
%{idp.attribute.resolver.LDAP.searchFilter}
50
]]>
51
</FilterTemplate>
52
<ConnectionPool
53
minPoolSize="%{idp.pool.LDAP.minSize:3}"
54
maxPoolSize="%{idp.pool.LDAP.maxSize:10}"
55
blockWaitTime="%{idp.pool.LDAP.blockWaitTime:PT3S}"
56
validatePeriodically="%{idp.pool.LDAP.validatePeriodically:true}"
57
validateTimerPeriod="%{idp.pool.LDAP.validatePeriod:PT5M}"
58
validateDN="%{idp.pool.LDAP.validateDN:}"
59
validateFilter="%{idp.pool.LDAP.validateFilter:(objectClass=*)}"
60
expirationTime="%{idp.pool.LDAP.idleTime:PT10M}"/>
61
</DataConnector>
62
63
</AttributeResolver>
64
Copied!

attribute-filter.xml

The attribute-filter.xml file has been updated to release several of the attributes mapped by the LDAPDirectory data connector as well as the user name that will be used as the identity within PowerShell Universal.
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
This file is an EXAMPLE policy file. While the policy presented in this
4
example file is illustrative of some simple cases, it relies on the names of
5
non-existent example services and the example attributes demonstrated in the
6
default attribute-resolver.xml file.
7
8
This example does contain some usable "general purpose" policies that may be
9
useful in conjunction with specific deployment choices, but those policies may
10
not be applicable to your specific needs or constraints.
11
-->
12
<AttributeFilterPolicyGroup id="ShibbolethFilterPolicy"
13
xmlns="urn:mace:shibboleth:2.0:afp"
14
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
15
xsi:schemaLocation="urn:mace:shibboleth:2.0:afp http://shibboleth.net/schema/idp/shibboleth-afp.xsd">
16
17
<AttributeFilterPolicy id="example1">
18
<PolicyRequirementRule xsi:type="ANY" />
19
<AttributeRule attributeID="username">
20
<PermitValueRule xsi:type="ANY" />
21
</AttributeRule>
22
<AttributeRule attributeID="displayName">
23
<PermitValueRule xsi:type="ANY" />
24
</AttributeRule>
25
<AttributeRule attributeID="uid">
26
<PermitValueRule xsi:type="ANY" />
27
</AttributeRule>
28
<AttributeRule attributeID="mail">
29
<PermitValueRule xsi:type="ANY" />
30
</AttributeRule>
31
<AttributeRule attributeID="sn">
32
<PermitValueRule xsi:type="ANY" />
33
</AttributeRule>
34
</AttributeFilterPolicy>
35
36
37
38
</AttributeFilterPolicyGroup>
39
Copied!