Spring Security: Ошибка ввода-вывода MySQL при регистрации нескольких пользователей

0

Я пытаюсь зарегистрироваться и войти в систему с помощью Spring Security, а также предоставить им роли, которые требуются весной. В настоящее время я получаю следующую ошибку при регистрации нескольких пользователей.

Ошибка:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Дублирующая запись 'USER' для ключа 'UK_8sewwnpamngi6b1dwaa88askk'

Имя роли может быть одинаковым для многих пользователей, поэтому я сделал "id" для ролей, который является первичным ключом, и автогенерируется. В моей таблице "USER_ROLES" в моей базе данных MySQL есть только одна запись, которая является первым адресом электронной почты и именем роли "ПОЛЬЗОВАТЕЛЬ". В таблице Customer есть все записи, независимо от ошибок. Я буду продолжать работать над этим.

Спасибо, что посмотрели.

Customer.java

package com.example.demo.models;

import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

@Entity
public class Customer implements Serializable {

    @NotNull
    @Size(min=2, max=25)
    private String name;

    @GeneratedValue
    @Id
    private int accountNumber;

    private BigDecimal accountFunds;

    @NotNull
    @Size(min=2)
    private String password;

    @NotNull
    @Size(min=2, max=25)
    @Email
    private String email;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "USER_ROLES", joinColumns = {
            @JoinColumn(name = "CUSTOMER_EMAIL", referencedColumnName = "email")
    }, inverseJoinColumns = {
            @JoinColumn(name = "ROLE_NAME", referencedColumnName = "name")
    })
    private List<Role> roles;

    public Customer(String name, String password, String email) {
        this.name = name;
        this.password = password;
        this.email = email;
    }

    public Customer() {}

    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAccountNumber() {
        return accountNumber;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public BigDecimal getAccountFunds() {
        return accountFunds;
    }

    public void setAccountFunds(BigDecimal accountFunds) {
        this.accountFunds = accountFunds;
    }

}

Role.java

package com.example.demo.models;


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

@Entity
public class Role {

    @Id
    @GeneratedValue
    private int id;

    private String name;

    @ManyToMany(mappedBy = "roles")
    private List<Customer> customers;


    public Role(String name, List<Customer> customers) {
        this.name = name;
        this.customers = customers;
    }

    public Role(String name) {
        this.name = name;
    }

    public Role() {}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Customer> getCustomers() {
        return customers;
    }

    public void setCustomers(List<Customer> customers) {
        this.customers = customers;
    }
}

UserService.java

package com.example.demo.models.services;

import com.example.demo.models.Customer;
import com.example.demo.models.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

public void createUser(Customer customer) {

    Role userRole = new Role("USER");
    List<Role> roles = new ArrayList<>();
    BCryptPasswordEncoder  encoder = new BCryptPasswordEncoder();
    customer.setPassword(encoder.encode(customer.getPassword()));
    roles.add(userRole);
    customer.setRoles(roles);

    userRepository.save(customer);
    }

    public void createAdmin(Customer customer) {

    Role userRole = new Role("ADMIN");
    List<Role> roles = new ArrayList<>();
    BCryptPasswordEncoder  encoder = new BCryptPasswordEncoder();
    customer.setPassword(encoder.encode(customer.getPassword()));
    roles.add(userRole);
    customer.setRoles(roles);

    userRepository.save(customer);

    }
}

UserRepository

package com.example.demo.models.services;

import com.example.demo.models.Customer;
import org.springframework.data.jpa.repository.JpaRepository;


public interface UserRepository extends JpaRepository<Customer, String> {
}

SecurityConfig

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.sql.DataSource;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("select email as principal, password as credentials, true from customer where email=?")
                .authoritiesByUsernameQuery("select customer_email as principal, role_name as role from user_roles where customer_email=?")
                .passwordEncoder(passwordEncoder()).rolePrefix("ROLE_");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers(
                        "/**/webjars/**",
                        "/cheese/signup",
                        "/cheese/login",
                        "/cheese/success").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/cheese/login")
                .defaultSuccessUrl("/cheese/account")
                .permitAll();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
Теги:
spring-security
spring
jdbc
spring-data-jpa

1 ответ

0

Хорошо, поэтому я получил его на работу. SecurityConfig - это ТОЛЬКО, за исключением того, что вам нужно изменить 'role_name' на 'role_id'.

Чтобы дать немного объяснений, я сделал следующее:

  1. Добавьте идентификатор в роли, сделайте его Первичным ключом/автогенерированным.
  2. Для Клиента "многие ко многим" я присоединился к электронной почте клиента (обратное присоединение) к роли "id"
  3. Для роли я сделал сопоставление "один ко многим". присоединение к роли "id" с электронной почтой клиента (обратного соединения).

Таким образом, я столкнулся с таблицей "user_roles", где role_id был сопоставлен с электронной почтой клиента и таблицей "role", где role_id была сопоставлена с ролью (например, "USER", "ADMIN" и т.д.), Что позволяет для дубликатов. Я все еще новичок, поэтому, возможно, даже это не лучший способ сделать это, но это сработало для меня.

Код...

Customer.java

package com.example.demo.models;

import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

@Entity
public class Customer implements Serializable {

    @NotNull
    @Size(min = 2, max = 25)
    private String name;

    @GeneratedValue
    @Id
    private int accountNumber;

    private BigDecimal accountFunds;

    @NotNull
    @Size(min = 2)
    private String password;

    @NotNull
    @Size(min = 2, max = 25)
    @Email
    private String email;

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="user_roles",
            joinColumns={@JoinColumn(name="CUSTOMER_EMAIL", referencedColumnName = "email")},
            inverseJoinColumns={@JoinColumn(name="ROLE_ID", referencedColumnName="id")})
    private List<Role> roles;

    public Customer(String name, String password, String email) {
        this.name = name;
        this.password = password;
        this.email = email;
    }

    public Customer() {}

    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAccountNumber() {
        return accountNumber;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public BigDecimal getAccountFunds() {
        return accountFunds;
    }

    public void setAccountFunds(BigDecimal accountFunds) {
        this.accountFunds = accountFunds;
    }
}

Role.java

package com.example.demo.models;


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

@Entity
public class Role {

    @Id
    @GeneratedValue
    private int id;

    private String name;

    @OneToMany(cascade=CascadeType.ALL)
    @JoinTable(name="user_roles",
            joinColumns={@JoinColumn(name="ROLE_ID", referencedColumnName="id")},
            inverseJoinColumns={@JoinColumn(name = "CUSTOMER_EMAIL", referencedColumnName = "email")
    })
    private List<Customer> customers;


    public Role(String name, List<Customer> customers) {
        this.name = name;
        this.customers = customers;
    }

    public Role(String name) {
        this.name = name;
    }

    public Role() {}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Customer> getCustomers() {
        return customers;
    }

    public void setCustomers(List<Customer> customers) {
        this.customers = customers;
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню