当前位置: 首页 > 知识库问答 >
问题:

为什么Spring Security在这个Spring Boot REST API项目上不起作用?它总是给我“403禁止”错误

穆商震
2023-03-14

我正在开发一个Spring Boot1.4.1应用程序(该应用程序实现了一些REST web服务),并且在尝试将Spring Security性实现到这个项目中时发现了一些困难。

我有以下情况:

1)我有CustomUserDetails实现Spring Security UserDetails接口:

import com.betrivius.domain.User;
import com.betrivius.domain.UserRole;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

public class CustomUserDetails extends User implements UserDetails {

    private static final long serialVersionUID = 1L;


    public CustomUserDetails(User user){
        super(user);
    }


    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
        for(UserRole role : this.getUserRoles() ){
            GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName());
            authorities.add(grantedAuthority);
        }

        return authorities;
    }

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

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

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

}
import com.betrivius.dao.UserDAO;
import com.betrivius.domain.User;
import com.betrivius.security.bean.CustomUserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService{
    @Autowired
    private UserDAO userDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userDao.findByUsername(username);
        if(user == null){
            throw new UsernameNotFoundException("No user present with username: "+username);
        }else{
            return new CustomUserDetails(user);
        }
    }

}
import com.betrivius.security.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomUserDetailsService.class)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordencoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/Accomodation/**").access("hasRole('ROLE_USER')")
                .anyRequest().permitAll()
                .and()
                .csrf().disable();

  /*.and()
    .formLogin().loginPage("/login")
    .usernameParameter("username").passwordParameter("password")
  .and()
    .logout().logoutSuccessUrl("/login?logout") 
   .and()
   .exceptionHandling().accessDeniedPage("/403")
  .and()
    .csrf();*/
    }

    @Bean(name = "passwordEncoder")
    public PasswordEncoder passwordencoder() {
        return new BCryptPasswordEncoder();
    }
}
.antMatchers("/Accomodation/**").access("hasRole('ROLE_USER')")

4)这是UserDAO,它获取了前面CustomUserDetailsService类中使用的用户信息:

@Repository
@Transactional(propagation = Propagation.MANDATORY)
public interface UserDAO extends JpaRepository<User, Long> {

    User findByUsername(String username);

    @Query("SELECT r FROM User u JOIN u.userRoles r where u.username = :username")
    List<UserRole> findRoleByUserName(String username);
}

用户名和密码位于DB中,它们是:

用户名:ErSabba

http://localhost:8080/Accomodation/7

正如您所看到的,问题是将正确的用户名和密码插入到基本身份验证html" target="_blank">表单中,它会给我403个错误,拒绝访问。

我认为这意味着我已经执行了身份验证,但我没有授权。

奇怪的是,我也试图把坏的凭据和我总是获得相同的401而不是坏的凭据错误。

User user = userDao.findByUsername(username);

共有1个答案

傅峻
2023-03-14

我建议你做一个没有DB的测试。您可以提供inmemory配置,如下所示:

auth.inMemoryAuthentication().withUser("ErSabba").password("pswd").authorities("ROLE_USER");

然后尝试登录。如果它能起作用,它将显示DB中的凭据有问题。

如何在数据库中存储密码?如果它是纯文本,它将不起作用,因为你有密码编码器,它应该读取你的密码作为一个散列。

 类似资料:
  • 问题内容: 我有一个合作伙伴,已经为我创造了一些内容供您抓取。 我可以使用浏览器访问该页面,但是当尝试使用user时,会显示。 我尝试使用,但这无济于事-可能是因为我不知道该去哪里。 1)我有什么办法可以刮取数据? 2)如果否,并且不允许合作伙伴将服务器配置为允许我访问,该怎么办? 我尝试使用的代码: 问题答案: 这不是您脚本中的问题,而是合作伙伴Web服务器安全性中的一项功能。 很难确切地说出是

  • 所以我有java的后端和Angular的前端。当我向我的spring boot restendpoint发送删除请求时,我得到了403代码。Angular发送第一个选项请求,并返回403,因此不会发生删除请求。另外,获取和发布工作正常。 我试过禁用csrf,但没有成功。我也在我的浏览器中使用它,所以我不应该禁用它。在soapUI中,DELETE可以正常工作。 这是我的安全配置类 我想做这个删除请求

  • 因此,下面的代码,从txt文件中取序列号作为参数,在我的计算机上正常工作。每个数字都写在一行上。下面是代码: 但它在CodeEval中不起作用。站点编译器是这么说的: Fontconfig错误:无法加载默认配置文件线程“main”java.awt.HeadLessException:未设置X11显示变量,但此程序执行了需要它的操作。在java.awt.GraphicsEnvironment.Che

  • 问题内容: 我正在尝试通过以下方式将日期范围划分为各个日期: 而且我不知道为什么不起作用,因为日期仍然相同,所以循环变得无限。 问题答案: plusDays不会改变原始的,您必须分配结果:

  • 以下代码未通过编译。这给了我一个错误: 变量h可能尚未初始化

  • 问题内容: 嗨,我只是想创建一个简单的golang应用程序,它使用以下命令在identi.ca上发布新的凹痕 到目前为止,这是我的代码,恕我直言,这应该起作用,但实际上它不起作用,有人知道如何解决此问题吗? 编辑: 不:我没有收到任何错误消息:/ 问题答案: 不会将整个命令行作为单个参数。您需要将其称为: 您怎么知道是否遇到错误?您无需检查的返回值。 您实际上应该将命令创建与运行分开。这样,您可以