对于我的RESTfulll应用程序,我们需要两种身份验证。一种是基于LDAP的所有内部员工。这是最近实施的,并且运行良好。对于所有外部员工,我们需要一些基于令牌的身份验证。
那是什么意思?这些员工将通过电子邮件发送生成的令牌,该令牌及其到期日期存储在我们的数据库中。员工应该能够使用该令牌“登录”。那么实现这样的最佳方法是什么?
我的第一个想法是建立一个额外的ExternalAuthenticationProvider
并将其添加到安全配置中。这行得通,用户可以使用令牌作为username
登录,然后获得JWT。但是,当他们喜欢访问任何资源时,响应就是一个HTTP 403
错误。
对我来说,这种实现看起来像是一个肮脏的hack,我不喜欢这种方法,也许有更好的方法。
谢谢您的建议。
@Component
public class ExternalAuthenticationProvider implements AuthenticationProvider {
@Autowired
private ExternalEffortLinkManagementRepository externalEffortLinkManagementRepository;
@Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
Collection<GrantedAuthority> gas = new HashSet<GrantedAuthority>();
String userToken = auth.getName();
ExternalEffortLinkManagement token = externalEffortLinkManagementRepository.getByLink(userToken);
if (token != null && token.isActive()) {
gas.add(new SimpleGrantedAuthority(SecurityConstants.ROLE_EXTERNAL));
return new UsernamePasswordAuthenticationToken(userToken, null, gas);
} else {
throw new
BadCredentialsException("External system authentication failed");
}
}
@Override
public boolean supports(Class<?> auth) {
return auth.equals(UsernamePasswordAuthenticationToken.class);
}
}
答案 0 :(得分:0)
我发现了错误:
代码段1:
gas.add(new SimpleGrantedAuthority(SecurityConstants.ROLE_EXTERNAL)); // ROLE_EXTERNAL = "EXTERNAL"
被替换为
代码段2:
gas.add(new SimpleGrantedAuthority("ROLE_" + SecurityConstants.ROLE_EXTERNAL));
我对LDAP认证使用了相同的代码(代码段1),因此我只是将字符串"EXTERNAL"
传递给了SimpleGrantedAuthority
构造函数。但是我是在CustomLdapAuthoritiesPopulator
中完成此操作的,好像spring在隐藏的代码中以某种方式添加了ROLE_
前缀。但这对我的ExternalAuthenticationProvider
不起作用,有必要在字符串中添加ROLE_
。