Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring Security中使用电子邮件作为用户名?_Java_Spring_Spring Security - Fatal编程技术网

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。