【问题标题】:Springboot security config not redirecting to successUrlSpring Boot 安全配置未重定向到成功 URL
【发布时间】:2018-10-14 16:38:42
【问题描述】:

我似乎不明白我的代码有什么问题。我正在尝试使用 Springboot 安全登录,一切似乎都正确,我可以在控制台上看到我的用户名和密码。谁能告诉我我做错了什么?

这是我的 SecSecurityConfig 类

     package com.scanapp.config;
     import com.scanapp.repositories.RoleRepository;
     import com.scanapp.services.UserDetailsService;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.beans.factory.annotation.Qualifier;
     import org.springframework.context.annotation.Bean;
     import org.springframework.context.annotation.Configuration;
     import 
     org.springframework.security.authentication.dao.DaoAuthenticationProvider;
     import org.springframework.security.crypto.password.PasswordEncoder;

     @Configuration
     @EnableWebSecurity
     public class SecSecurityConfig extends WebSecurityConfigurerAdapter {


     @Autowired
     private RoleRepository roleRepository;




    @Autowired
    @Qualifier("myuserdet")
    UserDetailsService userDetailsService;
    protected void init(AuthenticationManagerBuilder auth) throws Exception {
        System.out.println("I'm here");
        auth.authenticationProvider(authProvider());
    }

    @Bean
    public DaoAuthenticationProvider authProvider() {
        System.out.println("got here");
        DaoAuthenticationProvider authProvider = new 
       DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(passwordEncoder());
        return authProvider;
    }


    @Bean
    public PasswordEncoder passwordEncoder()
      {

        return new CustomPassword();
       }

        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http.authorizeRequests()
                    .antMatchers("/resources**").permitAll()
                    .anyRequest().permitAll()
                    .and().formLogin().loginPage("/login").successForwardUrl("/index").defaultSuccessUrl("/index",true).failureUrl("/login?error").permitAll()
                    .and()
                    .csrf().disable();
        System.out.println("got here too");
        }

    }

UserServiceDetails.java

package com.scanapp.services;

import com.drew.metadata.StringValue;
import com.scanapp.config.MyUserPrincipal;
import com.scanapp.config.SecSecurityConfig;
import com.scanapp.models.User;
import com.scanapp.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Objects;


@Qualifier("myuserdet")
@Service
public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {

    @Autowired
    private UserRepository userRepository;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {


        User user = userRepository.findByEmail(username);

        if (Objects.nonNull(user)) {
            MyUserPrincipal principal = new MyUserPrincipal(user);
            System.out.println(String.valueOf(principal));
            System.out.println("User Found");
            System.out.println(principal.getPassword());
            System.out.println(principal.getUsername());
            return principal;
        }else {
            throw new BadCredentialsException("User Not found");
        }

    }
}

MyUserPrincipal.java

package com.scanapp.config;

import com.scanapp.models.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

public class MyUserPrincipal implements UserDetails {



        private User user;

        public MyUserPrincipal(User user) {
            this.user = user;
        }


    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {

            return null;
    }

    @Override
    public String getPassword()
    {
        return user.getPassword();
    }

    @Override
    public String getUsername()
    {
        return user.getEmail();
    }

    @Override
    public boolean isAccountNonExpired() {
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }

    @Override
    public boolean isEnabled() {
        return false;
    }
}

CustomPassword.java

package com.scanapp.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class CustomPassword extends BCryptPasswordEncoder {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public String encode(CharSequence rawPassword) {
        return super.encode(rawPassword);
    }

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        System.out.println("paasword etered {}" + rawPassword);
        return super.matches(rawPassword, encodedPassword);
    }
}

【问题讨论】:

  • 尽管如此,仍然值得删除,因为它无论如何都使用了 :)

标签: java spring-boot spring-security


【解决方案1】:

尝试从配置中删除此块。理论上 Spring 会在幕后创建所有这些 bean(自动获取您的 passwordEncoder 和 UserDetailsS​​ervice)。

@Autowired
@Qualifier("myuserdet")
UserDetailsService userDetailsService;
protected void init(AuthenticationManagerBuilder auth) throws Exception {
    System.out.println("I'm here");
    auth.authenticationProvider(authProvider());
}

@Bean
public DaoAuthenticationProvider authProvider() {
    System.out.println("got here");
    DaoAuthenticationProvider authProvider = new 
   DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService);
    authProvider.setPasswordEncoder(passwordEncoder());
    return authProvider;
}

如果它不起作用,请尝试重命名您的 UserDetailsS​​ervice(尽管这是一个很长的尝试)。

【讨论】:

  • 它不会工作。 “重命名”UserDetailsS​​ervice 是什么意思?
  • 将该类重命名为其他名称。你真的试过去掉那些豆子吗?
  • 好的,我改名了,但还是一样的。如果我删除 bean,我应该配置其他东西吗?我对春天真的很陌生
【解决方案2】:

您的代码中有很多杂音。

1.您定义了仅扩展 BCryptPasswordEncoder 的 CustomPassword。我建议返回

@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

2。您定义了另一个用户模型,它什么都不做,并且授予权限的列表为空。这很奇怪,因为如果权限列表为空,它应该会失败。请返回导入

org.springframework.security.core.userdetails.User;

//..
return new User(userName, encodedPassword, Collections.singletonList(new SimpleGrantedAuthority("USER")

3.最好为你的豆子使用其他名称,而不是春天的。请将 UserDetailsS​​ervice 重命名为 CustomUserDetailsS​​ervice 并且不要在您的配置中使用限定符。

4.请确保当您将密码保存在数据库中时,使用 BCryptPasswordEncoder 对其进行哈希处理。

【讨论】:

    【解决方案3】:

    好的。另一个想法: 根据文档,此方法不应返回 null:

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
    
            return null;
    }
    

    返回AuthorityUtils.NO_AUTHORITIES;

    理论上,在您的 UserDetailsS​​ervice 创建主体之后,它可以在身份验证期间引发NullpointerException。如果那里有一个通用的catch (Exception e),那么它将简单地嵌入到一个AuthenticationException中。

    --- 编辑

    哎哟!

    您还应该在MyUserPrincipal类的最后四个方法中将返回值更改为true

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }
    
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }
    
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }
    
    @Override
    public boolean isEnabled() {
        return true;
    }
    

    您的 princapal 总是被禁用和过期等等。当然是不允许登录的! :)

    【讨论】:

    • 遗憾的是,即使返回了 AuthorityUtils.NO_AUTHORITIES,我仍然无法登录
    猜你喜欢
    • 2016-10-26
    • 2016-12-22
    • 2020-07-29
    • 2020-03-06
    • 2018-05-19
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 2014-02-05
    相关资源
    最近更新 更多