Dan*_*elf 5 spring-security spring-boot spring-security-saml2
我希望有人能给我一个比我在文档中找到的更具体的例子。
使用 SpringBoot/Spring Security 5.6.0。我正在将基于 SpringSecurity/SAML 的身份验证过程迁移到SAML2。
我需要将根据responseToken信息构建的UserDetails添加到身份验证中。就像我们在文档中可以读到的内容: https: //docs.spring.io/spring-security/reference/5.6.0-RC1/servlet/saml2/index.html#servlet-saml2login-opensamlauthenticationprovider-userdetailsservice
但我不明白第三点:返回包含用户详细信息的自定义身份验证:“return MySaml2Authentication(userDetails,authentication);”
在任何情况下,您都必须执行“return new MySaml2Authentication(userDetails,authentication);” 正确的?
无论如何,当该过程继续时,它会被执行:
身份验证authenticate =provider.authenticate(authentication);
我们可以看到,它用原始值替换了“详细信息”值。
authenticationResponse.setDetails(authentication.getDetails());
/**
* @param authentication the authentication request object, must be of type
* {@link Saml2AuthenticationToken}
* @return {@link Saml2Authentication} if the assertion is valid
* @throws AuthenticationException if a validation exception occurs
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
try {
Saml2AuthenticationToken token = (Saml2AuthenticationToken) authentication;
String serializedResponse = token.getSaml2Response();
Response response = parse(serializedResponse);
process(token, response);
AbstractAuthenticationToken authenticationResponse = this.responseAuthenticationConverter
.convert(new ResponseToken(response, token));
if (authenticationResponse != null) {
authenticationResponse.setDetails(authentication.getDetails());
}
return authenticationResponse;
}
catch (Saml2AuthenticationException ex) {
throw ex;
}
catch (Exception ex) {
throw createAuthenticationException(Saml2ErrorCodes.INTERNAL_VALIDATION_ERROR, ex.getMessage(), ex);
}
}
Run Code Online (Sandbox Code Playgroud)
如何添加依赖于从令牌获取的信息的 UserDetails?我无法扩展 OpenSaml4AuthenticationProvider 因为它是“final”。
并在 MySaml2AuthenticationManager 中执行身份验证后设置详细信息authenticate =provider.authenticate(authentication); 但这对我来说似乎不对。
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider();
provider.setResponseAuthenticationConverter(responseToken -> {
Saml2Authentication auth = OpenSaml4AuthenticationProvider
.createDefaultResponseAuthenticationConverter()// First, call the default converter, which extracts attributes and authorities from the response
.convert(responseToken);
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
String role = getRole(auth.getName());
grantedAuthorities.add(new SimpleGrantedAuthority(role));
Saml2Authentication saml2Authentication = new Saml2Authentication((AuthenticatedPrincipal) auth.getPrincipal(), auth.getSaml2Response(), grantedAuthorities);
/*
//The details are replaced by the authentication.getDetails().
MyUserDetails userDetails = new MyUserDetails(authenticate.getName(),auth.getPrincipal());
saml2Authentication.setDetails(userDetails);
*/
return saml2Authentication;
});
Authentication authenticate = provider.authenticate(authentication);
//Doesn't sound like a good idea
if ((authenticate.getPrincipal() instanceof DefaultSaml2AuthenticatedPrincipal)) {
DefaultSaml2AuthenticatedPrincipal samlPrincipal = (DefaultSaml2AuthenticatedPrincipal) authenticate.getPrincipal();
MyUserDetails userDetails = new MyUserDetails(authenticate.getName(),
samlPrincipal.getFirstAttribute("SMFIRSTNAME")
, samlPrincipal.getFirstAttribute("SMLASTNAME")
, samlPrincipal.getFirstAttribute("SMEMAIL"));
((Saml2Authentication)authenticate).setDetails(defaultDISUserDetails);
}
return authenticate;
Run Code Online (Sandbox Code Playgroud)
还有更好的选择吗?
非常感谢您的帮助
此致
小智 1
我想通这一点也太晚了。但您实际上应该使用自己的 AbstractAuthenticationToken 实现,并使用额外的字段来填充您自己的对象。这是我的:
public class CustomSaml2Authentication extends Saml2Authentication {
private User user;
public CustomSaml2Authentication(AuthenticatedPrincipal principal, String saml2Response,
Collection<? extends GrantedAuthority> authorities) {
super(principal, saml2Response, authorities);
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
877 次 |
| 最近记录: |