Spring Security 6与数据库中的用户进行身份验证和授权[已关闭]

64jmpszr  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(65)

已关闭。此问题需要更多focused。目前不接受回答。
**要改进此问题吗?**更新此问题,使其仅针对editing this post的一个问题。

上个月关门了。
Improve this question
我有一个项目,如网上食品 Spring 订购系统平台,我使用Hibernate与两个模型,像这样:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String username;
    private String password;
    private String email;
    private Long balance;
}

个字符
我认为这个系统有三个角色:ROLE_SYSAADMIN,ROLE_ADMIN(食品商店),ROLE_CUSTOMER Users和UsersRole存储在数据库中。
如何使用Sping Boot 6为我的应用配置授权和身份验证?
我搜索并做了一些代码。首先,我写了一个自定义的UserDetailService像这样

@Service
public class HiruezUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;
    
    public HiruezUserDetailsService(UserRepository userRepository) {
        super();
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));
        return new HiruezUserDetails(user);
    }

}


然后,自定义UserDetails,如:

public class HiruezUserDetails implements UserDetails {
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private final User user;

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

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Collections.singleton(new SimpleGrantedAuthority("ROLE_" + user.getRole().getName()));
    }

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

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

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

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

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

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

}


最后一个是SecurityConfig.java像:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Autowired
    private HiruezUserDetailsService hiruezUserDetailsService;
    
    @Bean
    public PasswordEncoder passwordEncoder( ) {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public JdbcUserDetailsManager jdbcUserDetailManager() {
        JdbcUserDetailsManager userDetailManager = new JdbcUserDetailsManager();
        userDetailManager.setJdbcTemplate(jdbcTemplate);
        return userDetailManager;
    }
    
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .userDetailsService(hiruezUserDetailsService)
            .passwordEncoder(passwordEncoder());
    }
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authorize) -> authorize
                .requestMatchers("/admin/**").hasRole("SYSADMIN")
                .requestMatchers("/store/**").hasRole("ADMIN")
                .requestMatchers("/customer/**").hasRole("CUSTOMER")
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults())
            .formLogin(form -> form
                    .loginPage("/login")
                    .permitAll()
                )
            .logout((logout) -> logout.logoutUrl("/logout"));

        return http.build();
    }
}


但我工作....嗯
拜托,帮我修好或者给予我另一种方法。非常感谢。

pnwntuvh

pnwntuvh1#

让我们看看如何解决这个问题

  • 使用管理员先前设置的新列roleId更新用户表实体
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "users")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password;
    private String email;
    private Long balance;

    private Long roleId; // new field , this field will set when admin create user by selecting role

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

        List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
        //authorities.add(new SimpleGrantedAuthority("ROLE_SYSADMIN"));
        //authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
        //authorities.add(new SimpleGrantedAuthority("ROLE_CUSTOMER"));

        // we will set the permission leater

        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

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

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

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

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

字符串

  • 用户存储库表
public interface UserRepository extends JpaRepository<User, Long> {
}

  • 用户角色表和存储库
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user_roles")
public class UserRole {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
}

public interface UserRoleRepository extends JpaRepository<UserRole, Long> {
}

  • 创建自定义身份验证提供程序,以便从用户角色表中读取权限名称,并用于身份验证和授权
@Component
@RequiredArgsConstructor
public class UserAuthenticationProvider implements AuthenticationProvider, UserDetailsService {

    private final UserRepository userRepository;
    private final UserRoleRepository userRoleRepository;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        final String username = (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName();
        if (Utils.isEmpty(username)) {
            throw new BadCredentialsException("invalid login details");
        }
        // get user details using Spring security user details service
        UserDetails user = null;
        try {
            user = loadUserByUsername(username);

        } catch (UsernameNotFoundException exception) {
            throw new BadCredentialsException("invalid login details");
        }
        return createSuccessfulAuthentication(authentication, user);
    }

    private Authentication createSuccessfulAuthentication(final Authentication authentication, final UserDetails user) {

        User dbUser =  userRepository.findByUsername(user.getUsername());
        UserRole userRole = userRoleRepository.findById(dbUser.getRoleId());

        List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority(userRole.getName()));

        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user.getUsername(), authentication.getCredentials(), authorities);
        token.setDetails(authentication.getDetails());
        return token;
    }

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

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

        return userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
    }
}

  • 根据您的需要更新您的安全性,但使用上述身份验证提供程序
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
    private final UserAuthenticationProvider userAuthenticationProvider;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // ...
                .authenticationProvider(userAuthenticationProvider);
        return http.build();
    }
}

相关问题