如何覆盖 SAMLAuthenticationProvider 中的 NameID 值?
How to override the NameID value in SAMLAuthenticationProvider?
我正在使用 Spring 安全 SAML 1.0.1。我的应用程序使用此 XML 配置 SAMLAuthenticationProvider
bean :
<!-- SAML Authentication Provider responsible for validating of received SAML messages -->
<b:bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider">
<!-- OPTIONAL property: can be used to store/load user data after login -->
<b:property name="userDetails">
<b:bean class="eu.ueb.acem.services.auth.SamlAuthenticationUserDetailsService"/>
</b:property>
<b:property name="forcePrincipalAsString" value="false"/>
</b:bean>
class "SamlAuthenticationUserDetailsService" 实现了 loadUserBySAML(SAMLCredential)
方法。如果数据库中不存在该用户,则创建该用户。
@Override
public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException {
logger.info("entering loadUserBySAML({})", credential);
String userID = credential.getNameID().getValue();
logger.info("{} is logged in", userID);
Map<String, String> mapOfAttributesFriendlyNamesAndValues = new HashMap<String, String>();
mapOfAttributesFriendlyNamesAndValues.put("eduPersonAffiliation", null);
mapOfAttributesFriendlyNamesAndValues.put("eduPersonPrincipalName", null);
mapOfAttributesFriendlyNamesAndValues.put("eduPersonPrimaryAffiliation", null);
mapOfAttributesFriendlyNamesAndValues.put("supannEtablissement", null);
mapOfAttributesFriendlyNamesAndValues.put("supannEntiteAffectationPrincipale", null);
mapOfAttributesFriendlyNamesAndValues.put("supannOrganisme", null);
mapOfAttributesFriendlyNamesAndValues.put("displayName", null);
mapOfAttributesFriendlyNamesAndValues.put("mail", null);
mapOfAttributesFriendlyNamesAndValues.put("givenName", null);
mapOfAttributesFriendlyNamesAndValues.put("sn", null);
mapOfAttributesFriendlyNamesAndValues.put("uid", null);
for (Attribute attribute : credential.getAttributes()) {
logger.info("attribute friendly name={}", attribute.getFriendlyName());
if (mapOfAttributesFriendlyNamesAndValues.containsKey(attribute.getFriendlyName())) {
// We set the values of the property
for (XMLObject attributeValueXMLObject : credential.getAttribute(attribute.getName()).getAttributeValues()) {
logger.info("We care about this attribute, getAttributeValue={}", getAttributeValue(attributeValueXMLObject));
mapOfAttributesFriendlyNamesAndValues.put(attribute.getFriendlyName(), getAttributeValue(attributeValueXMLObject));
}
}
else {
logger.info("We don't care about this attribute");
}
}
Person user = usersService.getUser(mapOfAttributesFriendlyNamesAndValues.get("eduPersonPrincipalName"));
user.setLogin(mapOfAttributesFriendlyNamesAndValues.get("eduPersonPrincipalName"));
user.setEmail(mapOfAttributesFriendlyNamesAndValues.get("mail"));
user.setName(mapOfAttributesFriendlyNamesAndValues.get("displayName"));
user.setAdministrator(true);
user = usersService.updatePerson(user);
logger.info("leaving loadUserBySAML");
return loadUserByUser(user);
}
private UserDetails loadUserByUser(Person targetUser) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
// Roles
if (targetUser.isAdministrator()) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
else {
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
return new User(targetUser.getLogin(), targetUser.getPassword(),
true, // enabled
true, // account not expired
true, // credentials not expired
true, // account not locked
authorities);
}
我有以下行为:
- 我在我的 SP 上请求一个需要身份验证的页面
- 我被重定向到 IDP(最好是发现服务)
- IDP 正确returns 凭据
- 我的
loadUserBySAML
方法被调用
- 如果用户不存在,则会在数据库中创建一个与其电子邮件地址相同的登录名
- 请求的页面加载并且创建的用户未被重复使用,而是创建一个新用户,其登录名等于
credential.getNameID().getValue()
的值(例如“_246558c0d7c514447292d750df577b6b”)。
问题 : 如何将凭据的 "NameID" 属性设置为电子邮件地址?
我已经多次阅读 the documentation 的“9.4 身份验证对象”部分,但我仍然不明白如何告诉 Spring 安全部门应该引用我的 UserDetails
对象使用电子邮件地址而不是 NameID 值。
我认为问题可能是 SAMLAuthenticationProvider
默认情况下总是使用 NameID
,即使 UserDetails
从 SAMLUserDetailsService
返回。这样做是为了与以前的版本向后兼容,尽管我正在考虑更改它以避免混淆。
为了使用从您的 UserDetails
返回的值,在 bean SAMLAuthenticationProvider
.
上将 属性 forcePrincipalAsString
设置为 false
我正在使用 Spring 安全 SAML 1.0.1。我的应用程序使用此 XML 配置 SAMLAuthenticationProvider
bean :
<!-- SAML Authentication Provider responsible for validating of received SAML messages -->
<b:bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider">
<!-- OPTIONAL property: can be used to store/load user data after login -->
<b:property name="userDetails">
<b:bean class="eu.ueb.acem.services.auth.SamlAuthenticationUserDetailsService"/>
</b:property>
<b:property name="forcePrincipalAsString" value="false"/>
</b:bean>
class "SamlAuthenticationUserDetailsService" 实现了 loadUserBySAML(SAMLCredential)
方法。如果数据库中不存在该用户,则创建该用户。
@Override
public Object loadUserBySAML(SAMLCredential credential) throws UsernameNotFoundException {
logger.info("entering loadUserBySAML({})", credential);
String userID = credential.getNameID().getValue();
logger.info("{} is logged in", userID);
Map<String, String> mapOfAttributesFriendlyNamesAndValues = new HashMap<String, String>();
mapOfAttributesFriendlyNamesAndValues.put("eduPersonAffiliation", null);
mapOfAttributesFriendlyNamesAndValues.put("eduPersonPrincipalName", null);
mapOfAttributesFriendlyNamesAndValues.put("eduPersonPrimaryAffiliation", null);
mapOfAttributesFriendlyNamesAndValues.put("supannEtablissement", null);
mapOfAttributesFriendlyNamesAndValues.put("supannEntiteAffectationPrincipale", null);
mapOfAttributesFriendlyNamesAndValues.put("supannOrganisme", null);
mapOfAttributesFriendlyNamesAndValues.put("displayName", null);
mapOfAttributesFriendlyNamesAndValues.put("mail", null);
mapOfAttributesFriendlyNamesAndValues.put("givenName", null);
mapOfAttributesFriendlyNamesAndValues.put("sn", null);
mapOfAttributesFriendlyNamesAndValues.put("uid", null);
for (Attribute attribute : credential.getAttributes()) {
logger.info("attribute friendly name={}", attribute.getFriendlyName());
if (mapOfAttributesFriendlyNamesAndValues.containsKey(attribute.getFriendlyName())) {
// We set the values of the property
for (XMLObject attributeValueXMLObject : credential.getAttribute(attribute.getName()).getAttributeValues()) {
logger.info("We care about this attribute, getAttributeValue={}", getAttributeValue(attributeValueXMLObject));
mapOfAttributesFriendlyNamesAndValues.put(attribute.getFriendlyName(), getAttributeValue(attributeValueXMLObject));
}
}
else {
logger.info("We don't care about this attribute");
}
}
Person user = usersService.getUser(mapOfAttributesFriendlyNamesAndValues.get("eduPersonPrincipalName"));
user.setLogin(mapOfAttributesFriendlyNamesAndValues.get("eduPersonPrincipalName"));
user.setEmail(mapOfAttributesFriendlyNamesAndValues.get("mail"));
user.setName(mapOfAttributesFriendlyNamesAndValues.get("displayName"));
user.setAdministrator(true);
user = usersService.updatePerson(user);
logger.info("leaving loadUserBySAML");
return loadUserByUser(user);
}
private UserDetails loadUserByUser(Person targetUser) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
// Roles
if (targetUser.isAdministrator()) {
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
else {
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
}
return new User(targetUser.getLogin(), targetUser.getPassword(),
true, // enabled
true, // account not expired
true, // credentials not expired
true, // account not locked
authorities);
}
我有以下行为:
- 我在我的 SP 上请求一个需要身份验证的页面
- 我被重定向到 IDP(最好是发现服务)
- IDP 正确returns 凭据
- 我的
loadUserBySAML
方法被调用 - 如果用户不存在,则会在数据库中创建一个与其电子邮件地址相同的登录名
- 请求的页面加载并且创建的用户未被重复使用,而是创建一个新用户,其登录名等于
credential.getNameID().getValue()
的值(例如“_246558c0d7c514447292d750df577b6b”)。
问题 : 如何将凭据的 "NameID" 属性设置为电子邮件地址?
我已经多次阅读 the documentation 的“9.4 身份验证对象”部分,但我仍然不明白如何告诉 Spring 安全部门应该引用我的 UserDetails
对象使用电子邮件地址而不是 NameID 值。
我认为问题可能是 SAMLAuthenticationProvider
默认情况下总是使用 NameID
,即使 UserDetails
从 SAMLUserDetailsService
返回。这样做是为了与以前的版本向后兼容,尽管我正在考虑更改它以避免混淆。
为了使用从您的 UserDetails
返回的值,在 bean SAMLAuthenticationProvider
.
forcePrincipalAsString
设置为 false