为什么应用程序看不到 Spring Security 中的 Roles (Forbidden)

Art*_*yan 5 java roles spring-security spring-boot

有一个Spring-MVC项目,其中有三种类型的用户:Customer、Admin、Cook。所有这些都是从类继承的User。角色是在没有 的情况下创建的ENUM,只需通过静态字符串常量(在User类中显示)。添加后Spring Security,授权成功,但是当我尝试执行其中一个类(Customer、Admin 或 Cook)的方法时,它给出了json 错误 403:

{
  "timestamp": "2020-05-08T19:48:43.999+0000",
  "status": 403,
  "error": "Forbidden",
  "message": "Forbidden",
  "path": "/admin/cooks"
}
Run Code Online (Sandbox Code Playgroud)

请告诉我我做错了什么。错在哪里。

用户:

package com.tinychiefdelights.model;

import io.swagger.annotations.ApiModel;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Collection;
import java.util.Collections;

@ApiModel
@Data
@Entity
@Table(name = "pg_user", schema = "public")
public class User implements UserDetails {

    // Roles
    //
    public static final String ROLE_ADMIN = "ADMIN";
    public static final String ROLE_CUSTOMER = "CUSTOMER";
    public static final String ROLE_COOK = "COOK";
    //


    public User() { // ?????? ??????????? ??? Hibernate

    }


    // ????
    private @Id
    @GeneratedValue
    Long id;

    @Column(name = "login")
    private String login;

    @Size(min = 5, max = 30)
    @Column(name = "password")
    private String password;

    @Column(name = "role")
    private String role;

    @Column(name = "name")
    private String name;

    @Column(name = "last_name")
    private String lastName;


    // ??????
    //
    // GrantedAuthority
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + role));
    }


    // userName == login (???? ? ????)
    @Override
    public String getUsername() {
        return login;
    }


    // ?? ???? ?????? ????? TRUE, ??? ??? ??? ?? ????????????
    @Override
    public boolean isAccountNonExpired() {
        return true;
    }


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


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


    @Override
    public boolean isEnabled() {
        return true;
    }
    //
}
Run Code Online (Sandbox Code Playgroud)

例如我只添加了一个班级管理员:

行政:

package com.tinychiefdelights.model;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.persistence.*;

@ApiModel
@Data
@Entity
@Table(name = "pg_user", schema = "public")
public class Admin {

    public Admin() { // ?????? ??????????? ??? Hibernate

    }

    // ????

    // name, lastName, login, password ????? ?? ?????? User ????? ?????;

    @ApiModelProperty
    private @Id
    @GeneratedValue
    Long id;


    // Relationships
    //
    @ApiModelProperty
    @OneToOne
    @JoinColumn(name = "id") // Join without Admin in User class
    private User user;
}
Run Code Online (Sandbox Code Playgroud)

管理服务:

@Service
public class AdminService extends UserService {

    // ????
    //
    // Injects in setters
    private AdminRepository adminRepository; // ?????????????

    private OrderRepository orderRepository; // ?????

    private CookRepository cookRepository; // ?????

    private CustomerRepository customerRepository; // ????????


    // Getters and Setters
    //
    // ?????? inject ????? ???????
    @Autowired
    public void setAdminRepository(AdminRepository adminRepository) {
        this.adminRepository = adminRepository;
    }

    @Autowired
    public void setOrderRepository(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    @Autowired
    public void setCookRepository(CookRepository cookRepository) {
        this.cookRepository = cookRepository;
    }

    @Autowired
    public void setCustomerRepository(CustomerRepository customerRepository) {
        this.customerRepository = customerRepository;
    }


    // ??????
    //
    // ????? ?????? ???? ???????
    public List<Order> getAllOrders() {
        return orderRepository.findAll();
    }


    // ????? ?????????? ?? ??????????? ??????
    public Order getOrderInfo(Long id) {
        try {
            return orderRepository.getById(id);
        } catch (NotFoundException e) {
            throw new NotFoundException(id);
        }
    }


    // ????? ?????? ?? ID
    public Cook getCook(Long id) {
        try {
            return cookRepository.getByIdAndUserRole(id, "COOK");
        } catch (NotFoundException e) {
            throw new NotFoundException(id);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException();
        }
    }


    // ???????? ????? ??????
    public void editCook(Long id, User user, float rating, String aboutCook) {
        Cook cook = cookRepository.getByIdAndUserRole(id, "COOK");
        try {
            cook.setUser(user);
            cook.setRating(rating);
            cook.setAboutCook(aboutCook);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException();
        } catch (NotFoundException e) {
            throw new NotFoundException(id);
        }
    }


    // ????? ???? ???????
    public List<Cook> getAllCooks() {
        return cookRepository.findByUserRole("COOK");
    }


    // ??????? ??????
    public void deleteCook(Long id) {
        Cook cook = cookRepository.getByIdAndUserRole(id, "COOK");
        try {
            cookRepository.delete(cook);
        } catch (Exception e) {
            throw new NotFoundException(id);
        }
    }


    // ????? ???? ??????????
    public List<Customer> getAllCustomers() {
        return customerRepository.findByUserRole("CUSTOMER");
    }


    // ????? ????????? ?? ID
    public Customer getCustomer(Long id) {
        try {
            return customerRepository.getByIdAndUserRole(id, "CUSTOMER");
        } catch (NotFoundException e) {
            throw new NotFoundException(id);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

管理员控制器:

@Api(value = "?????? ? ???????", tags = {"?????????????"})
@RestController
@RequestMapping("/admin")
@RolesAllowed("ADMIN")
public class AdminController {

    // Constructor
    //
    // Inject ????? ???????????
    @Autowired
    public AdminController(AdminRepository adminRepository, AdminService adminService, UserService userService) {
        this.adminRepository = adminRepository;
        this.adminService = adminService;
        this.userService = userService;
    }


    // ????
    // All injects into constructor
    private final AdminRepository adminRepository;

    private final AdminService adminService;

    private final UserService userService;


    // ??????
    //
    // GET MAPPING
    //
    // ????? ?????? ???? ???????
    @GetMapping("/orders")
    List<Order> getAllOrders() {
        return adminService.getAllOrders();
    }


    // ????? ?????????? ?? ??????????? ?????? ?? ID
    @GetMapping("/order/{id}")
    Order getOrderInfo(@PathVariable Long id) {
        return adminService.getOrderInfo(id);
    }


    // ????? ???? ???????
    @GetMapping("/cooks")
    List<Cook> getAllCooks() {
        return adminService.getAllCooks();
    }


    // ????? ?????? ?? ID
    @GetMapping("/cook/{id}")
    Cook getCook(@PathVariable Long id) {
        return adminService.getCook(id);
    }


    // ????? ???? ?????????????
    @GetMapping("/customers")
    List<Customer> getAllCustomer() {
        return adminService.getAllCustomers();
    }


    // ????? ????????? ?? ID
    @GetMapping("/customer/{id}")
    Customer getCustomer(@PathVariable Long id) {
        return adminService.getCustomer(id);
    }


    // POST MAPPING
    //


    // PUT MAPPING
    //
    // ???????? ?????? ?? ID
    @PutMapping("/edit/cook/{id}")
    void editCook(@PathVariable Long id, User user, @PathVariable float rating, String aboutCook) {
        adminService.editCook(id, user, rating, aboutCook);
    }

    // ???????? ??????
    @PutMapping("/change/password")
    void changePassword(@RequestParam String login, @RequestParam String newPass) {
        userService.changePassword(login, newPass);
    }


    // DELETE MAPPING
    //
    // ??????? ??????????? ?????? ?? ID
    @DeleteMapping("/delete/cook/{id}")
    void removeCook(@PathVariable Long id) {
        adminService.deleteCook(id);
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用注释@RolesAllowed。

SpringWebConfig:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    // ????
    //
    private UserService userService;

    private PasswordEncoder passwordEncoder;



    // Injects in SETTERS
    //
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Autowired
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }



    // Methods
    //
    // ??? ?? ?????????????? ????? ????????????
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }


    // ??? ?? ?????????????? ??? ?????? ? ??????? ??
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
    }


    // Beans
    //
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userService);
        authenticationProvider.setPasswordEncoder(passwordEncoder);
        return authenticationProvider;
    }


    @Bean
    public static PasswordEncoder getPasswordEncoder() {
        return new BCryptPasswordEncoder(8);
    }


    // ?????????? ?????? ??????????? ??? userDetService
    @Bean
    public UserDetailsService userDetailsService() {
        return userService;
    }
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

Art*_*yan 3

要解决此问题,请在方法的最开始的WebSecurityConfig类中添加以下内容:configure

http
.cors().disable()
.csrf().disable()
Run Code Online (Sandbox Code Playgroud)