java 在应用程序属性中使用UserDetailsService配置基本身份验证以供多次使用

jjhzyzn0  于 2022-11-20  发布在  Java
关注(0)|答案(1)|浏览(83)

bounty将在6天后过期。回答此问题可获得+100的声望奖励。rahul s正在寻找标准答案

我有多个用户,我想将它们配置到spring-boot的UserDetailsService中进行基本身份验证。
User具有用其标记的附加字段id

import org.springframework.security.core.userdetails.UserDetails;

public class User implements UserDetails {
    private final String username;
    private final String password;
    private final String id;

    private static final String ROLE_USER = "ROLE_USER";

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(ROLE_USER);
        return Stream.of(simpleGrantedAuthority).collect(Collectors.toList());
    }

    // Getter & setter
}

属性yml看起来像:

basic-auth:
    oliver:
        password: twist
        id: 1
    ruskin:
        password: bond
        id: 2
    mark:
        password: twain
        id: 3

UserDetailsService中,我不确定如何使用应用程序属性动态配置用户。

public class UserService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) {

        String encodedPassword = passwordEncoder.encode( // How to fetch password );

        String id = // How to fetch id

        return new User(username, encodedPassword, id);
    }
}
jtoj6r0c

jtoj6r0c1#

你可以用不同的方法来做。
例如,让我们假设您的基本身份验证属性YAML文件,为了简单起见,只做了最少的调整:

basic-auth:
    users:
        oliver:
            password: twist
            id: 1
        ruskin:
            password: bond
            id: 2
        mark:
            password: twain
            id: 3

要使您的UserDetailsService服务可以访问此信息,您可以使用@ConfigurationProperties封装此信息,如下所示:

@Component
@ConfigurationProperties(prefix = "basic-auth")
public class BasicAuthProperties {
  private Map<String, Credential> users = new HashMap<>();

  // Getter & setter

  // Convenient method
  public Optional<Credential> getCredential(String username) {
    Optional.ofNullable(users.get(username)); 
  }

  public static class Credential {
        
    private int id;
    private String password;
        
    // Getter & setter
        
  }
}

UserDetailsService中使用此@ConfigurationProperties

public class UserService implements UserDetailsService {

  private final BasicAuthProperties basicAuthProperties;

  public UserService(BasicAuthProperties basicAuthProperties) {
    this.basicAuthProperties = basicAuthProperties;
  }

  @Override
  public UserDetails loadUserByUsername(String username) {
    Optional<BasicAuthProperties.Credential> optCredential = basicAuthProperties.getCredential(username);
    if (!optCredential.isPresent()) {
      // handle as appropriate, consider at least logging it
      return null;
    }

    BasicAuthProperties.Credential credential = optCredential.get();
    String encodedPassword = passwordEncoder.encode(credential.getPassword());
    // I assume int, the value is numeric in your YAML file, but modify it
    // if necessary
    int id = credential.getId();
    return new User(username, encodedPassword, id);
  }
}

相关问题