spring 作为401未授权返回的请求

ars1skjm  于 2023-01-24  发布在  Spring
关注(0)|答案(1)|浏览(154)

我最近问了一个非常类似的问题,但我得到的错误是403(禁止),而不是401,但我改变了整个代码,所以我决定张贴一个新的具体到这个代码和这个问题。
我试图为我的项目创建一个用户逻辑(有史以来第一次),但它一直不可能实现任何类型的安全措施。我已经被困在这几天,所以如果有人知道我错在哪里,我将不胜感激!
这是我的代码:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/users/create", "/users/create/**").permitAll()
                .and()
            .httpBasic();
    }
}
@Data
@Component
public class CreateUserRoleDTO {
    private Integer idUser;
    
    private List<Integer> idsRoles;

    public CreateUserRoleDTO() {
        super();
    }
    
    public CreateUserRoleDTO(Integer idUser, List<Integer> idsRoles) {
        super();
        this.idUser = idUser;
        this.idsRoles = idsRoles;
    }

    public Integer getIdUser() {
        return idUser;
    }

    public void setIdUser(Integer idUser) {
        this.idUser = idUser;
    }

    public List<Integer> getIdsRoles() {
        return idsRoles;
    }

    public void setIdsRoles(List<Integer> idsRoles) {
        this.idsRoles = idsRoles;
    }       
}
@Service
public class CreateRoleUserService {
    
    @Autowired
    private UserRepository repo;

    @Autowired
    private CreateUserRoleDTO createUserRoleDTO;
    
    public Users execute(CreateUserRoleDTO createUserRoleDTO) {
        Optional<Users> userExists=repo.findById(createUserRoleDTO.getIdUser());
        List<Roles> roles=new ArrayList<>();
        
        if (userExists.isEmpty()) {
            throw new Error("User does not exist");
        }
        roles=createUserRoleDTO.getIdsRoles().stream().map(role -> {
            return new Roles(role);
        }).collect(Collectors.toList());
        
        Users user=userExists.get();
        user.setRole(roles);
        
        repo.save(user);
        return user;    
    }
@Entity
    @Table(name="users_table")
    public class Users implements Serializable{
        
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;
        
        @Column(unique=true)
        private String login;
        
        @Column(unique=true)
        private String email; 
        
        private String password;
        
        @ManyToMany
        private List<Roles> role; 
        
    }

(plus getter、setter和构造函数)
data.sql

INSERT INTO `ROLES`(`ID`, `NAME`) VALUES(1, 'USER');
INSERT INTO `ROLES`(`ID`,`NAME`) VALUES(2, 'ADMIN');
rjzwgtxy

rjzwgtxy1#

SecurityConfig中缺少身份验证配置。例如,尝试将以下内容添加到configure方法中:

http.httpBasic();

此外,您的安全配置缺少默认授权规则,因此实际上不需要身份验证。您可以尝试添加.anyRequest().authenticated()来测试此功能。
下面是一个使用DSL中可用的lambda语法的配置,它可以升级到Spring Security 6:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authorize) -> authorize
                .antMatchers("/users/create", "/users/create/**").permitAll()
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults());

        // Disable CSRF for testing.
        // TODO: Delete the following line and learn about CSRF!
        http.csrf().disable();

        return http.build();
    }

    @Bean // Automatically injected into Spring Security
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // Note: We don't configure a UserDetailsService since it is already 
    // annotated @Service and therefore already published as an @Bean.

}

不幸的是,我还发现了您的应用程序中的一些其他错误,使它无法工作。
看起来您在用于查询UserDetailsService的用户的JPQL中有一个错误。WHERE子句应该是where u.login = :username(添加一个u.)。
你也可以反转if语句,当抛出UsernameNotFoundException时(在这种情况下比Error更好的异常),它看起来像:

@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Users user = repo.findByUsernameFetchRoles(username);
        if (user == null) {
            throw new UsernameNotFoundException("User does not exist!");
        }

        return UserPrincipal.create(user);
    }

最后,Users类的构造函数没有从user参数中分配用户数据。

public UserPrincipal(Users user) {
        this.login = user.getLogin();
        this.password = user.getPassword();
        ...
    }

有了这些更改,身份验证就可以正常工作,您就可以开始学习Spring Security了!

相关问题