Java 如何在Spring Security中使用电子邮件作为用户名?
我必须从我的Java 如何在Spring Security中使用电子邮件作为用户名?,java,spring,spring-security,Java,Spring,Spring Security,我必须从我的用户类中删除一个登录字段,并在SecurityUtils中将电子邮件用作用户名 我已经在前端更改了j_username参数,但现在问题仍然存在于后端 public static String getCurrentUserLogin() { SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication authentication = securi
用户
类中删除一个登录字段,并在SecurityUtils中将电子邮件
用作用户名
我已经在前端更改了j_username
参数,但现在问题仍然存在于后端
public static String getCurrentUserLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
String userName = null;
if (authentication != null) {
if (authentication.getPrincipal() instanceof UserDetails) {
UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
userName = springSecurityUser.getUsername();
} else if (authentication.getPrincipal() instanceof String) {
userName = (String) authentication.getPrincipal();
}
}
return userName;
}
因此,userName
为空,因为UserDetails
和Authentication
没有电子邮件。如何将email
字段设置为“j_用户名”?我试过这个
解决方案,但这还不够,因为我使用的是匿名用户
public class DomainUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public DomainUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(final String login) {
String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
Optional<User> userFromDatabase = userRepository.findOneByLogin(lowercaseLogin);
return userFromDatabase.map(user -> {
if (!user.getActivated()) {
throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated");
}
List<GrantedAuthority> grantedAuthorities = user.getAuthorities().stream()
.map(authority -> new SimpleGrantedAuthority(authority.getName()))
.collect(Collectors.toList());
return new org.springframework.security.core.userdetails.User(lowercaseLogin,
user.getPassword(),
grantedAuthorities);
}).orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the " +
"database"));
}
}
此外,我还有一个UserDetailsService
的实现,但在调试时,作为anonymousUser
public class DomainUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
public DomainUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(final String login) {
String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
Optional<User> userFromDatabase = userRepository.findOneByLogin(lowercaseLogin);
return userFromDatabase.map(user -> {
if (!user.getActivated()) {
throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated");
}
List<GrantedAuthority> grantedAuthorities = user.getAuthorities().stream()
.map(authority -> new SimpleGrantedAuthority(authority.getName()))
.collect(Collectors.toList());
return new org.springframework.security.core.userdetails.User(lowercaseLogin,
user.getPassword(),
grantedAuthorities);
}).orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the " +
"database"));
}
}
公共类DomainUserDetailsService实现UserDetailsService{
私有最终用户存储库用户存储库;
公共域UserDetailsService(UserRepository UserRepository){
this.userRepository=userRepository;
}
@凌驾
public UserDetails loadUserByUsername(最终字符串登录){
String lowercaseLogin=login.toLowerCase(Locale.ENGLISH);
可选userFromDatabase=userRepository.findOneByLogin(小写字母);
返回userFromDatabase.map(用户->{
如果(!user.getActivated()){
抛出新的UserNotActivatedException(“用户”+小写字母+“未激活”);
}
List grantedAuthories=user.getAuthories().stream()
.map(authority->new SimpleGrantedAuthority(authority.getName()))
.collect(Collectors.toList());
返回新的org.springframework.security.core.userdetails.User(小写字母),
user.getPassword(),
授权机构);
}).orelsetrow(()->new UsernameNotFoundException(“用户”+小写字母+”未在中找到”+
"资料库"),;
}
}
这里我分享了我的Spring安全配置类中的一些代码
.formLogin().loginPage("/login")
.usernameParameter("logInId").passwordParameter("password")
在这里,我使用'logInId'参数来登录,而不是默认参数
我想你在找这样的东西 为了实现您的目标,您必须控制匿名用户的行为。我以前有过这个问题,当用户登录时,查询工作正常。正如M.Denim建议的那样,您应该在这里通过电子邮件搜索->
可选的userFromDatabase=userRepository.findOneByEmail(小写字母);
但是如果是
getCurrentUserLogin()
中的匿名用户,则必须编写if语句返回anonymous@localhost
如果用户名=匿名用户
要明确告诉用户使用其电子邮件地址作为用户名,只需在前端的注册页面中添加说明即可。为什么您觉得需要为此更改后端中的变量名?因为它以前使用了登录字段。现在,它需要被删除,需要使用现场电子邮件代替。但是,当用户未通过身份验证时,仍会调用此方法getCurrentUserLogin
,因为系统使用了anonymousUser
,当它搜索用户名时,它在username
中给出null,该字段在前端的命名方式对您在后端如何使用该字段没有影响。您仍然可以使用j_username
字段使用email
列查询数据库。更改前端字段的名称对正在执行的查询没有影响。您需要更改查询以从数据库中获取用户,而不是前端中字段的名称。同样,在前端调用什么参数并不重要。。。它可能是foobarbaz
。它仅由Spring Security用于确定要检索并传递到UserDetailsService
的参数。因此,再次在前端更改它并不重要。重要的是您对userdetails服务的实现。它使用存储库中的方法,假设SpringDataJPA存储库仍然使用登录字段。该方法应命名为findOneByEmail
。所以再次不要更改前端,更改后端。再次,您需要做的唯一更改是更改您的存储库查询方法。。。Spring Security将完成其他所有工作。参数如何命名并不重要,方法参数的名称如何调用也不重要。重要的是如何在自定义userdetails服务中处理它。Spring Security将从请求中获取参数,并将其传递给UserDetailsService
仅此而已。关于重命名为findOneByEmail
的问题,我假设您的实体有一个电子邮件字段,否则它将不起作用,如果您使用专用查询,则需要更改它。我已经进行了设置,但它不会影响Authentication=securityContext.getAuthentication()代码>。它仍然查找用户名登录这只会更改来自前端的参数的名称,该参数将用作登录时使用的用户名/用户ID。