在springsecurity中,我从何处获取“username”值,以传递给userdetailsservice接口的loaduserbyusername(stringusername)方法

a5g8bdjr  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(443)

我试图通过基于用户名和密码对用户进行身份验证来从数据库中获取用户。我使用的是基本身份验证。我正在restapi的授权头中发送用户名和密码
在我的控制器中,getuser()方法调用userservice类的getuser()方法

@GetMapping("/user/self")
public ResponseEntity<UserDto> getUser() {
    UserDto UserDto = userService.getUser();
    return new ResponseEntity<>(UserDto, HttpStatus.OK);
}

@PutMapping("/user/self")
public ResponseEntity<User> updateUser(@Valid @RequestBody Map<String, String> userMap, Principal principal) {
    String username = principal.getName();
    String firstname = userMap.get("firstName");
    String lastName = userMap.get("lastName");
    String password = BCrypt.hashpw(userMap.get("password"), BCrypt.gensalt(10));
    User user = userService.getUserByUserName(username);
    user.setFirstName(firstname);
    user.setLastName(lastName);
    user.setPassword(password);
    userService.save(user);
    return new ResponseEntity<>(user, HttpStatus.NO_CONTENT);
}

userservice类实现userdetailsservice并重写loaduserbyusername方法,该方法要求将用户名作为参数传递。我的问题是:如何将username传递给从控制器调用的userservice类中的loaduserbyusername()方法。用户名值驻留在哪里?我的理解是-身份验证对象包含传递给身份验证对象的用户凭据当用户键入其凭据并发送其请求时,如何检索此用户名值

@Service
     public class UserService implements UserDetailsService {

@Autowired
UserRepository userRepository;

public UserDto save(User user) {
    String hashedPassword = BCrypt.hashpw(user.getPassword(), BCrypt.gensalt(10));
    user.setPassword(hashedPassword);
    userRepository.save(user);
    UserDto userDto = new UserDto();
    userDto.setId(user.getId());
    userDto.setFirstName(user.getFirstName());
    userDto.setLastName(user.getLastName());
    userDto.setUserName(user.getUserName());
    userDto.setAccountUpdatedAt(user.getAccountUpdatedAt());
    userDto.setAccountCreatedAt(user.getAccountCreatedAt());
    return userDto;
}

@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
    User user = userRepository.findByUserName(userName);
    if (user == null) {
        throw new UsernameNotFoundException(userName + "was not found");
    }
    return new UserPrincipal(user);
}

这是我的存储库代码:

@Repository
    public interface UserRepository extends CrudRepository<User, Long> {

User findByUserName(String userName);
   }

这是我的身份验证码:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
DataSource dataSource;
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
@Autowired
UserService userService;

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

public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder());

}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().and().csrf().disable();
    http.authorizeRequests().antMatchers("/v1/user").permitAll()
            .antMatchers("/v1/user/self").authenticated().and().httpBasic()
            .authenticationEntryPoint(authenticationEntryPoint);
 }
}
798qvoo8

798qvoo81#

如果你在处理jpa,那么在你的情况下,你必须使用 userDetailsService 而不是 jdbcauthentication ,因此您的安全类将如下所示:

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private  UserService userService;

    public SecurityConfig(UserService userService){
        this.userService = userService;
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder(10); // Number of rounds 
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(this.userService).passwordEncoder(passwordEncoder());
    }
}

然后您可以在 UserService 类以满足以下示例中的业务需要:

@Service
public class UserService implements UserDetailsService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository){
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        Optional<User> user = userRepository.findByUsername(username);

        if(user.isPresent()){
            log.info("cretaed under User service : " + user.get());
            return user.get();
        }

        throw new UsernameNotFoundException("empty or invalud user");
    }
}

另外,不要忘记创建 findByUsername 方法也不要忘记实现 org.springframework.security.core.userdetails.UserDetails 在模块类中:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    Optional<User> findByUsername(String name);
}

相关问题