RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1121656
Accepted
Artur Vartanyan
Artur Vartanyan
Asked:2020-05-07 16:34:47 +0000 UTC2020-05-07 16:34:47 +0000 UTC 2020-05-07 16:34:47 +0000 UTC

添加 Spring Security 后出现 403 禁止错误

  • 772

我正在编写我的第一个战斗项目Spring MVC。有 3 个用户类别:Customer、Cook、Admin。它们都继承自@OneToOneUser关系类。因此,有 3 个控制器。添加后,我尝试测试方法,例如Admin的方法,控制台中没有一个错误,但它给出了以下错误:Spring SecurityGETSwagger json

{
  "timestamp": "2020-05-06T13:30:13.390+0000",
  "status": 403,
  "error": "Forbidden",
  "message": "Forbidden",
  "path": "/customer/change/password"
}
Response headers
 cache-control: no-cache, no-store, max-age=0, must-revalidate 
 connection: keep-alive 
 content-type: application/json 
 date: Wed, 06 May 2020 13:30:13 GMT 
 expires: 0 
 keep-alive: timeout=60 
 pragma: no-cache 
 transfer-encoding: chunked 
 x-content-type-options: nosniff 
 x-frame-options: DENY 
 x-xss-protection: 1; mode=block 

我去了WebSecurityConfig并从Customer hasRole中删除(我想过删除角色限制并在Swagger中运行它的方法,但是一样)。

网络安全配置:

package com.tinychiefdelights.configs;

import com.tinychiefdelights.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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;

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

    // Поля
    //
    private UserService userService;


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



    // Methods
    //
    // Тут мы переопределяем метод конфигураций
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/cook/**").hasRole("COOK");
//                .antMatchers("/customer/**").hasRole("CUSTOMER");
//                .anyRequest().authenticated()
//                .and()
//                .exceptionHandling()
//                .and()
//                .formLogin()
//                .loginPage("/login")
//                .permitAll()
//                .and()
//                .logout()
//                .permitAll();
    }


    // Тут мы переопределяем для работы с внешней БД
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }


    // Тут мы используем encoder для шифрования паролей
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    // Возвращаем сервис пользовател для userDetServ
    @Bean
    public UserDetailsService userDetailsService() {
        return userService;
    }
}

例如,这是 Customer 类:

顾客:

package com.tinychiefdelights.model;

import com.fasterxml.jackson.annotation.*;
import lombok.Data;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;

import javax.persistence.*;
import java.util.List;

@Data
@Entity
@Table(name = "customer", schema = "public")
public class Customer {

    public Customer() { // Пустой конструктор для Hibernate

    }


    // Поля

    // name, lastName, login, password берем от класса User через связи;

    private @Id
    @GeneratedValue
    Long id;

    @Column(name = "wallet")
    private double wallet;


    //Relationships
    //
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_id", referencedColumnName = "id") // Join without Customer in User class
    @NotFound(action = NotFoundAction.IGNORE)
    private User user;

    //Лист заказов
    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
    @JsonIgnore // Таким образом я предотвратил рекурсию
    private List<Order> orderList;
}

客户服务:

package com.tinychiefdelights.service;

import com.tinychiefdelights.exceptions.NotFoundException;
import com.tinychiefdelights.model.*;
import com.tinychiefdelights.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;


@Service
public class CustomerService extends UserService {

    // Поля
    //
    // Injects in setters
    private CustomerRepository customerRepository;

    private CookRepository cookRepository;

    private UserRepository userRepository;

    private OrderRepository orderRepository;

    private DishRepository dishRepository;

    private ReviewRepository reviewRepository;



    // SETTERS
    //
    // Injects into Setters
    @Autowired
    public void setReviewRepository(ReviewRepository reviewRepository) {
        this.reviewRepository = reviewRepository;
    }

    @Autowired
    public void setDishRepository(DishRepository dishRepository) {
        this.dishRepository = dishRepository;
    }

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


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

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

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



    // Методы
    //
    // Внести деньги на счет
    public void depositMoney(Long id, double money) {
        Customer customer = customerRepository.getByIdAndUserRole(id, Role.CUSTOMER);
        try {
            customer.setWallet(customer.getWallet() + money);
            customerRepository.save(customer);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException();
        } catch (NotFoundException e) {
            throw new NotFoundException(id);
        }

    }


    // Вывести деньги со счета
    public void withdrawMoney(Long id, double money) {
        Customer customer = customerRepository.getByIdAndUserRole(id, Role.CUSTOMER);
        if (money <= customer.getWallet()) { // Делаем проверку, чтобы сумма указанная заказчиком была меньше кошелька
            customer.setWallet(customer.getWallet() - money);
            customerRepository.save(customer);
        } else {
            throw new RuntimeException("Введенная Вами сумма превышает остаток на счете!");
        }
    }


    // Оставить Отзыв
    public void setReview(String text, int rate, Long id) {
        try {
            Review review = new Review();
            review.setReview(text);
            review.setRate(rate);
            review.setCook(cookRepository.getByIdAndUserRole(id, Role.COOK));
            reviewRepository.save(review);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException(e);
        }

    }


    // Сделать Заказ
    public void makeOrder(String address, String phoneNumber, Long customerId,
                          Long cookId, List<Long> dishListId, Date date) { // Сделать заказ ()

        try {
            Order order = new Order();
            order.setPhoneNumber(phoneNumber);
            order.setAddress(address);
            order.setDateOrder(date);
            order.setOrderStatus(true);
            order.setCustomer(customerRepository.getByIdAndUserRole(customerId, Role.CUSTOMER));
            order.setCook(cookRepository.getByIdAndUserRole(cookId, Role.COOK));
            /**Сделать через карзину**/
//            for (Long a: dishListId) {
//                dishList.add(dishRepository.getById(a));
//            }
//            order.setDishes(dishList);
            orderRepository.save(order);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException(e);
        }
    }


    // Изменить карточку заказчика
    public Customer editCustomer(Long id, User user, double wallet) {
        Customer customer = customerRepository.getByIdAndUserRole(id, Role.CUSTOMER);
        try {

            customer.setUser(user);
            customer.setWallet(wallet);
            return customerRepository.save(customer);

        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException();
        } catch (Exception e) {
            throw new NotFoundException(id);
        }
    }


    // Отменить заказ
    public void cancelOrder(Long id) {
        Order order = orderRepository.getById(id);
        order.setOrderStatus(false); // Добавим сообщение !!!!!!!!!!!!!!!
        orderRepository.save(order);
    }
}

客户控制器:

package com.tinychiefdelights.controller;

import com.tinychiefdelights.model.*;
import com.tinychiefdelights.repository.CustomerRepository;
import com.tinychiefdelights.service.CustomerService;
import com.tinychiefdelights.service.UserService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;


@Api(value = "Работа с Заказчиком", tags = {"Заказчик"})
@RestController
@RequestMapping("/customer")
public class CustomerController {

    //Constructor
    //
    // Injects через конструктор
    @Autowired
    public CustomerController(CustomerRepository customerRepository, CustomerService customerService, UserService userService) {
        this.customerRepository = customerRepository;
        this.customerService = customerService;
        this.userService = userService;
    }


    // Fields
    // Injects into constructor
    //
    private final CustomerRepository customerRepository;

    private final CustomerService customerService;

    private final UserService userService;


    // GET MAPPING
    //


    // POST MAPPING
    //
    // Сделать заказ
    @PostMapping("/make/order")
    public void makeOrder(String address, String phoneNumber, Long customerId,
                          Long cookId, @RequestParam List<Long> dishList, Date date) {
        customerService.makeOrder(address, phoneNumber, customerId, cookId, dishList, date);
    }


    // Оставить отзыв
    @PostMapping("/set/review")
    public void setReview(String text, int rate, Long id) {
        customerService.setReview(text, rate, id);
    }

    // PUT MAPPING
    //
    // Заказчик может редактировать свою карточку (поиск по ID)
    @PutMapping("/edit/{id}")
    Customer editCustomer(@PathVariable Long id, User user, @RequestParam double wallet) {
        return customerService.editCustomer(id, user, wallet);
    }


    // Снять деньги со своего депозита (Заказчик)
    @PutMapping("/{id}/withdraw/{money}")
    void withdrawMoney(@PathVariable Long id, @RequestParam double money) {
        customerService.withdrawMoney(id, money);
    }


    // Изменить свой пароль
    @PutMapping("/change/password")
    void changePassword(@RequestParam String login, @RequestParam String newPass) {
        userService.changePassword(login, newPass);
    }


    // Внести деньги на счет (Заказчик)
    @PutMapping("/{id}/deposit/money")
    public void depositMoney(@PathVariable Long id, @RequestParam double money) {
        customerService.depositMoney(id, money);
    }


    // Отменить Заказ
    @PutMapping("/cancel/order/{id}")
    public void cancelOrder(@PathVariable Long id){
        customerService.cancelOrder(id);
    }


    // DELETE MAPPING
    //
}

还有用户类,客户通过链接从中工作:

用户:

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 {

    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;

    @Enumerated(EnumType.STRING)
    @Column(name = "role")
    private Role 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;
    }
    //
}

枚举角色:

package com.tinychiefdelights.model;


public enum Role {

    COOK, ADMIN, CUSTOMER


}

P.S. В проекте нет Front'а вообще. Все методы я пробую в ручную через Swagger и до этого у меня все отлично работало! В чем может быть проблема?

Пробовал и без hasRole. Пробовал просто через @RolesAllowed, не помогает.

введите сюда описание изображения

java
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Artur Vartanyan
    2020-05-13T20:44:13Z2020-05-13T20:44:13Z

    Для того, чтобы пофиксить данную проблему, в WebSecurityConfig класс в метод configure в начало добавляем:

    http
    .cors().disable()
    .csrf().disable()
    
    • 4

相关问题

  • wpcap 找不到指定的模块

  • 如何以编程方式从桌面应用程序打开 HTML 页面?

  • Android Studio 中的 R.java 文件在哪里?

  • HashMap 初始化

  • 如何使用 lambda 表达式通过增加与原点的距离来对点进行排序?

  • 最大化窗口时如何调整元素大小?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5