Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.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 SecurityContextHolder.getContext().getAuthentication().getCredentials()在身份验证后返回null_Java_Spring Mvc_Spring Security - Fatal编程技术网

Java SecurityContextHolder.getContext().getAuthentication().getCredentials()在身份验证后返回null

Java SecurityContextHolder.getContext().getAuthentication().getCredentials()在身份验证后返回null,java,spring-mvc,spring-security,Java,Spring Mvc,Spring Security,我创建了一个简单的SpringWebMVC应用程序,但我有一个问题。在身份验证之后,我尝试获取一个身份验证对象,由于某种原因,它的凭据为空 在此项目中,我有一个自定义AuthenticationProvider,如下所示: @Component public class CustomAuthenticationProvider implements AuthenticationProvider { @Autowired private UserService userServi

我创建了一个简单的SpringWebMVC应用程序,但我有一个问题。在身份验证之后,我尝试获取一个身份验证对象,由于某种原因,它的凭据为空

在此项目中,我有一个自定义AuthenticationProvider,如下所示:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @PostConstruct
    public void init() {
        roleService.AddStandardRolesIfNeeded();
        userService.AddUserWithAdminRoleIfNotExists("a"); 
    }


    public Authentication authenticate(Authentication authentication) throws AuthenticationException {


        Object credentials = authentication.getCredentials();
        if(!(credentials instanceof String)) {
            return null;
        }

        String username = authentication.getName();
        String password = credentials.toString(); //password isn't null here


        User user = userService.findByUsernameAndPassword(username, password);


        if(user == null) {
            throw new BadCredentialsException("Authentication failed for " + username);
        }


        List<GrantedAuthority> authorities = new ArrayList<>();
        for(Role role : user.getRoles()) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }

        Authentication auth = new 
                UsernamePasswordAuthenticationToken(username, password, authorities);


        return auth;
    }

    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

我感兴趣的是,这是在spring security中故意做的,还是我遗漏了什么。

我通过将用户对象传递给UsernamePasswordAuthenticationToken构造函数,而不是将用户名传递给主体,解决了这个问题

我改变了这一点:

Authentication auth = new 
                UsernamePasswordAuthenticationToken(username, password, authorities);
为此:

Authentication auth = new 
                    UsernamePasswordAuthenticationToken(user, password, authorities);
在控制器中,我让用户这样:

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

我通过将用户对象传递给UsernamePasswordAuthenticationToken构造函数而不是用户名来解决这个问题

我改变了这一点:

Authentication auth = new 
                UsernamePasswordAuthenticationToken(username, password, authorities);
为此:

Authentication auth = new 
                    UsernamePasswordAuthenticationToken(user, password, authorities);
在控制器中,我让用户这样:

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

由于身份验证成功后将删除凭据,因此必须将橡皮擦凭据False添加到AuthenticationManagerBuilder配置中。就像下面的代码:

@Autowired
private CustomAuthenticationProvider customAuthProvider;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthProvider).eraseCredentials(false);
}

这已经晚了,但我认为根据问题,这是正确的答案。

因为认证成功后凭据将被删除,所以必须将橡皮擦凭据False添加到AuthenticationManagerBuilder配置中。就像下面的代码:

@Autowired
private CustomAuthenticationProvider customAuthProvider;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(customAuthProvider).eraseCredentials(false);
}

虽然已经晚了,但我认为这是问题的正确答案。

为什么要按用户名和密码搜索?您应该只按用户名搜索。然后在“身份验证”方法中比较密码?为什么按用户名和密码搜索?您应该只按用户名搜索。然后在authenticate方法中比较密码?我已经用这个配置尝试了好几次,它对我不起作用,getCredentials返回Null您可以详细说明customAuthProvider吗?那是什么东西?它应该实现/扩展什么?customAuthProvider是问题中提到的CustomAuthenticationProvider的对象。我已经更新了答案。我用这个配置尝试了好几次,它对我不起作用,getCredentials返回Null你能详细介绍一下customAuthProvider吗?那是什么东西?它应该实现/扩展什么?customAuthProvider是问题中提到的CustomAuthenticationProvider的对象。我已经更新了答案。