簡體   English   中英

Spring 用戶/密碼安全

[英]Spring security with user/password

因此,我遵循了一些關於 spring 安全性的用戶名和密碼指南,但其中大多數顯示使用“InMemoryUserDetailsManager”,他們說不應在生產中使用:

@Bean
public InMemoryUserDetailsManager userDetailsManager(){
    UserDetails admin = User.withDefaultPasswordEncoder()
            .username("ADMIN")
            .password("123")
            .roles("ADMIN").build();

    return new InMemoryUserDetailsManager(admin);
}

我的問題是,應該如何設置生產級別的版本? 它只是不使用默認密碼編碼器,因為它已被棄用,還是我應該使用完全不同的方法來添加和存儲用戶?

您應該實施 jdbc 身份驗證DaoAuthenticationProvider 結賬https://www.baeldung.com/spring-security-jdbc-authentication

您的用戶詳細信息必須存儲在永久存儲中,而不是臨時存儲中。 此外,必須對密碼進行加密以避免危及安全性。 因此,使用永久存儲,您可以獲取備份或數據並從中運行查詢。

您可以實現自定義用戶詳細信息服務,而不是使用默認服務。

@Service
public class CustomUserDetailsServiceImpl implements UserDetailsService {

    private final UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    public CustomUserDetailsServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);

        if(user == null) {
            throw ApiExceptionFactory.getApiException(ApiExceptionType.NOT_FOUND, "user");
        }

        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                user.getEnabled(),
                true,
                true,
                true,
                getAuthorities(user));
    }

    public Boolean isTokenValid(String token) {
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SECRET.getBytes()).parseClaimsJws(token);
            return true;
        } catch (SignatureException | MalformedJwtException | UnsupportedJwtException | IllegalArgumentException ex) {
            throw ApiExceptionFactory.getApiException(ApiExceptionType.LOGIN_FAILURE, "invalid credentials");
        } catch (ExpiredJwtException ex) {
            throw ApiExceptionFactory.getApiException(ApiExceptionType.LOGIN_FAILURE, "token expired");
        }
    }

    @Transactional
    public Boolean save(User user){
        if(StringUtils.isEmpty(user.getUsername())) {
            throw ApiExceptionFactory.getApiException(ApiExceptionType.BAD_REQUEST, "username");
        }

        if(StringUtils.isEmpty(user.getPassword())) {
            throw ApiExceptionFactory.getApiException(ApiExceptionType.BAD_REQUEST, "password");
        }

        if(StringUtils.isEmpty(user.getEmail())) {
            throw ApiExceptionFactory.getApiException(ApiExceptionType.BAD_REQUEST, "email");
        }

        User registeredUser = new User();
        registeredUser.setUsername(user.getUsername());
        registeredUser.setPassword(passwordEncoder.encode(user.getPassword()));
        registeredUser.setEmail(user.getEmail());
        registeredUser.setEnabled(true);
        registeredUser.setRoles(user.getRoles());

        User savedUser = userRepository.save(registeredUser);

        Inventory userInventory = inventoryService.saveInventoryForUser(savedUser.getUsername());

        return userInventory != null;
    }

    private Set<GrantedAuthority> getAuthorities(User user){
        Set<GrantedAuthority> authorities = new HashSet<>();
        for(Role role : user.getRoles()) {
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName().getRole());
            authorities.add(grantedAuthority);
        }
        return authorities;
    }
}

您可以將用戶詳細信息保存到您的存儲庫中。

@Repository
public interface UserRepository extends BaseRepository<User> {

    User findByUsername(String username);

    Boolean existsByUsername(String username);

    Boolean existsByEmail(String email);

}

最后將您的用戶詳細信息添加到帶有密碼編碼器的身份驗證管理器中。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(userDetailsServiceBean()).passwordEncoder(passwordEncoder());
    }

    @Override
    public UserDetailsService userDetailsServiceBean() {
        return new CustomUserDetailsServiceImpl(userRepository);
    }

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

有關詳細信息,請查看我的github 存儲庫

您好請編碼如下編碼

@Bean
public InMemoryUserDetailsManager createUserDetailsManager() {
    
    UserDetails userDetails1 = createNewUser("username1", "dummy");
    UserDetails userDetails2 = createNewUser("username2", "dummydummy");
    
    return new InMemoryUserDetailsManager(userDetails1, userDetails2);
}

private UserDetails createNewUser(String username, String password) {
    Function<String, String> passwordEncoder
    = input -> passwordEncoder().encode(input);

    UserDetails userDetails = User.builder()
                                .passwordEncoder(passwordEncoder)
                                .username(username)
                                .password(password)
                                .roles("USER","ADMIN")
                                .build();
    return userDetails;
}

希望對你有幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM