Second Office365 Domain requires different "Issuer URI"
Harald Strack
hstrack at ssystems.de
Sun May 21 17:47:52 EDT 2017
Hi Scott,
I implemented a responderIdLookupStrategy that changes the entityID of
the IdP based on the domain part of the user's email address. Here is
the configuration:
<bean name="mailContextResponderIdLookupStrategy"
class="de.ssystems.shibboleth.idp.relyingparty.MailContextResponderIdLookupStrategy"
p:defaultEntityId="%{idp.entityID}"
/>
<bean parent="RelyingPartyByName"
c:relyingPartyIds="#{{'urn:federation:MicrosoftOnline'}}">
<property name="profileConfigurations">
<list>
<bean parent="SAML2.SSO"
p:encryptAssertions="false"
p:signAssertions="true"
p:signResponses="false"
/>
<bean parent="SAML2.ECP"
p:encryptAssertions="false"
p:signAssertions="true"
p:signResponses="false"
p:nameIDFormatPrecedence="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
/>
<ref bean="SAML2.Logout" />
</list>
</property>
<property name="responderIdLookupStrategy">
<ref bean="mailContextResponderIdLookupStrategy" />
</property>
</bean>
The code is quite simple (prototype):
public class MailContextResponderIdLookupStrategy
extends
ResponderIdLookupFunction {
/** Strategy function to lookup {@link AttributeContext}. */
@Nonnull
private Function<ProfileRequestContext, AttributeContext>
attributeContextLookupStrategy;
/** Whether to look at filtered or unfiltered attributes. */
private boolean useUnfilteredAttributes;
private String defaultEntityId;
/** Constructor. */
public MailContextResponderIdLookupStrategy() {
attributeContextLookupStrategy = Functions
.compose(
new ChildContextLookup<>(AttributeContext.class),
new ChildContextLookup<ProfileRequestContext,
RelyingPartyContext>(
RelyingPartyContext.class));
useUnfilteredAttributes = true;
}
/** {@inheritDoc} */
@Override
@Nullable
public String apply(@Nullable final ProfileRequestContext input) {
if (input != null) {
final AttributeContext attributeCtx =
attributeContextLookupStrategy
.apply(input);
if (attributeCtx == null) {
return this.getDefaultEntityId();
}
final Map<String, IdPAttribute> attributes =
useUnfilteredAttributes
? attributeCtx.getUnfilteredIdPAttributes()
: attributeCtx.getIdPAttributes();
IdPAttribute domain = attributes.get("domain");
if (domain != null && domain.getValues() != null
&& domain.getValues().size() == 1) {
// Dynamic entityID based on domain of user, Metadata
exists
return this.getDefaultEntityId() + "/" +
domain.getValues().get(0);
}
return this.getDefaultEntityId();
}
return null;
}
public String getDefaultEntityId() {
return defaultEntityId;
}
public void setDefaultEntityId(String defaultEntityId) {
this.defaultEntityId = defaultEntityId;
}
public boolean isUseUnfilteredAttributes() {
return useUnfilteredAttributes;
}
public void setUseUnfilteredAttributes(boolean
useUnfilteredAttributes) {
this.useUnfilteredAttributes = useUnfilteredAttributes;
}
}
I tested three scenarios:
1) idp/profile/SAML2/POST/SSO - Login on Test SP works, but the audit
entry in idp-process.log shows the defaultEntityId. On the SP side the
dynamic entity ID will be shown as Shib-Identity-Provider header (good)
2) idp/profile/SAML2/SOAP/ECP - Test script works, but the audit entry
in idp-process.log shows the defaultEntityId. In the XML output of the
ECP testing script contains the dynamic entity ID as Issuer (good)
3) /idp/profile/SAML2/SOAP/ArtifactResolution - Login on test SP works,
unfortunately on the SP side the defaultEntityId will be shown as
Shib-Identity-Provider header (bad). If we save the dynamic entityID in
the user's session the first time the AttributeContext context is
available and return the dynamic entityId from there on, we get the
following error in the idp's log:
2017-05-21 22:26:21,900 - WARN
[org.opensaml.saml.saml2.profile.impl.ResolveArtifact:242] - Profile
Action ResolveArtifact: Artifact issuer mismatch, issued by
'https://www.example.com/idp/shibboleth' but IdP has entityID of
'https://www.example.com/idp/shibboleth/dynamic-part.com'
Is there a way around this when working with artifacts?
Actually 2 of 3 profiles did succeed... but it does not work with
artifacts. Not a Problem in our case, since office.com does not use
artifacts. However, I am still unsure if we should deploy such a dynamic
responderIdLookupStrategy as it may cause any other weired problems.
What do you think? Is it safe to use such a dynamic
responderIdLookupStrategy and is it conform to the specification?
thanks in advance
Harald
On 07.05.2017 18:28, Cantor, Scott wrote:
> On 5/6/17, 3:40 AM, "users on behalf of hstrack at ssystems.de" <users-bounces at shibboleth.net on behalf of shibboleth at ssystems.de> wrote:
>
>> So a decision to provide a dynamic IdP entity ID would be necessary based on
>> the users principalName, after the user has identified.
>
> I think I already answered that at some point in the past, but 3.3 allows a function to be injected to derive the entityID, and if it's done so as to return a fixed value until the user's identity is established and then returning a different value later, I doubt that's going to break anything. By the time the value is placed into the message I think the user will be identified.
>
> -- Scott
>
>
--
Harald Strack, Dipl.Inf.(FH)
IT Development
ssystems
Harald Strack
Kastanienallee 32
10435 Berlin
Tel: +49 30 2023 6071 - 1
http://www.ssystems.de
More information about the users
mailing list