未在spring security(SpringBoot)中更新OAuth2用户详细信息
我是spring security的新手,使用过jhipster,在其中我配置了基于db和LDAP的身份验证。现在,我已经使用@enableouthso将其与OAuth客户端集成。我可以使用外部OAuth Idp(Okta)进行身份验证,它正在重定向到我的应用程序,我的原则正在更新,我可以通过rest访问资源。但是我的userDetails对象没有填充未在spring security(SpringBoot)中更新OAuth2用户详细信息,spring,spring-security,oauth,jhipster,Spring,Spring Security,Oauth,Jhipster,我是spring security的新手,使用过jhipster,在其中我配置了基于db和LDAP的身份验证。现在,我已经使用@enableouthso将其与OAuth客户端集成。我可以使用外部OAuth Idp(Okta)进行身份验证,它正在重定向到我的应用程序,我的原则正在更新,我可以通过rest访问资源。但是我的userDetails对象没有填充 @Inject public void configureGlobal(AuthenticationManagerBuilder auth) {
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) {
try {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
auth
.ldapAuthentication()
.ldapAuthoritiesPopulator(ldapAuthoritiesPopulator)
.userDnPatterns("uid={0},ou=people")
.userDetailsContextMapper(ldapUserDetailsContextMapper)
.contextSource(getLDAPContextSource());
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
我已经深入检查了它失败的地方,并发现了以下问题
public static String getCurrentUserLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
String userName = null;
if (authentication != null) {
log.info("authentication is not null");
if (authentication.getPrincipal() instanceof UserDetails) { //failing here
log.info("principle is instance of userdetails");
UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
log.info(springSecurityUser.getUsername());
userName = springSecurityUser.getUsername();
} else if (authentication.getPrincipal() instanceof String) {
userName = (String) authentication.getPrincipal();
}
}
return userName;
}
它在生产线上失败了
if(authentication.getPrincipal() instanceof UserDetails)
处理此更新用户详细信息对象的可能和最佳方法是什么
更新:
@Transactional(readOnly = true)
public User getUserWithAuthorities() {
log.info("======inside getUserWithAuthorities =================");
log.info("current user is :::::::"+SecurityUtils.getCurrentUserLogin());
Optional<User> optionalUser = userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin());
User user = null;
if (optionalUser.isPresent()) {
user = optionalUser.get();
user.getAuthorities().size(); // eagerly load the association
}
return user;
}
@Transactional(readOnly=true)
公共用户GetUserWithAuthories(){
log.info(“=======内部GetUserWithAuthories===============================”);
log.info(“当前用户是:::”+SecurityUtils.getCurrentUserLogin());
可选选项user=userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin());
User=null;
if(optionalUser.isPresent()){
user=optionalUser.get();
user.getAuthories().size();//急切地加载关联
}
返回用户;
}
它试图从数据库中获取用户。但是用户不在数据库中类似于,我将重新创建OktaUserDetails类并铸造主体。然后,您可以保持大多数身份验证代码不变。下面是LDAP代码示例,OktaUserDetails的格式取决于JSON响应
} else if (authentication.getPrincipal() instanceof LdapUserDetails) {
LdapUserDetails ldapUser = (LdapUserDetails) authentication.getPrincipal();
return ldapUser.getUsername();
}
要保存从Oauth2资源接收的信息,请在SecurityConfiguration中声明PrincipalExtractor Bean。这允许您以自定义方式解析响应。下面是一个基本示例()
LDAP工作正常,因为在身份验证成功时,我将用户复制到应用程序数据库。实际上,问题在于基于OAuth的身份验证。在这种情况下,我从okta获得身份验证,但userdetails没有更新,因此我的ui显示为我是匿名用户。我已经试过auth成功处理程序,但它没有调用。对不起,我误解了你的问题。看起来您已经发现身份验证不是空的,并且您知道它不是UserDetails的
实例。您是否尝试添加else子句并记录authentication.getPrincipal()
包含的内容?它给出了一个字符串,其中我的名字和姓氏之间加了空格。您可以看到我为principle获得的实际json。下一个失败点是在UserService.GetUserWithAuthories中。我想创建一个新的OktaUser并将主体强制转换给该用户,以获取必要的信息并注入GetUserWithAuthories中的user对象。这是最好的方法吗?还是我应该尝试将用户复制到数据库中,这样在应用程序级别处理用户及其角色就不会更好了,我在LDAP中也是这样做的。我尝试使用身份验证成功处理程序,但未触发它。我不确定,我应该为此配置SecurityConfig文件吗?任何关于这一点的观点。我会根据你想要的“真相之源”来做出决定。如果您在登录时导入权限,那么它们在Okta上会发生更改,用户可以在您的应用程序中拥有额外的权限(我没有使用Okta,因此这可能是不正确的)。
@Bean
public PrincipalExtractor principalExtractor(UserRepository userRepository) {
return map -> {
String principalId = (String) map.get("id");
User user = userRepository.findByPrincipalId(principalId);
if (user == null) {
LOGGER.info("No user found, generating profile for {}", principalId);
user = new User();
user.setPrincipalId(principalId);
user.setCreated(LocalDateTime.now());
user.setEmail((String) map.get("email"));
user.setFullName((String) map.get("name"));
user.setPhoto((String) map.get("picture"));
user.setLoginType(UserLoginType.GOOGLE);
user.setLastLogin(LocalDateTime.now());
} else {
user.setLastLogin(LocalDateTime.now());
}
userRepository.save(user);
return user;
};
}