Spring security 如何在Spring Boot中植入Spring安全性

Spring security 如何在Spring Boot中植入Spring安全性,spring-security,spring-data,spring-boot,Spring Security,Spring Data,Spring Boot,我有一个springboot1.1.0.BUILD-SNAPSHOT项目,它使用springsecurity-springsecurity-web:4.0.0.M1。我想在H2表中为数据库表种子,但在启动时,生产测试代码和集成测试代码都会出现异常 以下是我的相关schema.sql文件内容: CREATE TABLE IF NOT EXISTS Users ( username VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY, password

我有一个springboot1.1.0.BUILD-SNAPSHOT项目,它使用springsecurity-springsecurity-web:4.0.0.M1。我想在H2表中为数据库表种子,但在启动时,生产测试代码和集成测试代码都会出现异常

以下是我的相关schema.sql文件内容:

CREATE TABLE IF NOT EXISTS Users (
  username VARCHAR_IGNORECASE(50)  NOT NULL PRIMARY KEY,
  password VARCHAR_IGNORECASE(500) NOT NULL,
  enabled  BOOLEAN                 NOT NULL
);

CREATE TABLE IF NOT EXISTS Authorities (
  username  VARCHAR_IGNORECASE(50) NOT NULL,
  authority VARCHAR_IGNORECASE(50) NOT NULL,
  CONSTRAINT fk_authorities_users FOREIGN KEY (username) REFERENCES users (username)
);
CREATE UNIQUE INDEX IF NOT EXISTS ix_auth_username ON authorities (username, authority);

INSERT INTO users(username,password,enabled) VALUES ('admin','$2a$10$GVPAMYRozI08Mcll5too6.Q4M2jTO0iJVoiaVDv9pMxRqTpxNj9vO', TRUE);
INSERT INTO Authorities (username, authority) VALUES ('admin', 'ADMIN');

INSERT INTO users(username,password,enabled) VALUES ('user','$2a$10$GVPAMYRozI08Mcll5too6.Q4M2jTO0iJVoiaVDv9pMxRqTpxNj9vO', TRUE);
INSERT INTO Authorities (username, authority) VALUES ('user', 'USER');
我的application.properties文件中包含以下内容:

spring.jpa.database=H2
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.generate-ddl=true
启动或运行测试时,出现以下错误:

Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement at line 1 of resource URL [file:/Users/David/projects/cnet/OFAC/out/test/OFAC/data.sql]: INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$GVPAMYRozI08Mcll5too6.Q4M2jTO0iJVoiaVDv9pMxRqTpxNj9vO', TRUE); nested exception is org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_4 ON PUBLIC.USERS(USERNAME)"; SQL statement:
INSERT INTO users (username, password, enabled) VALUES ('admin', '$2a$10$GVPAMYRozI08Mcll5too6.Q4M2jTO0iJVoiaVDv9pMxRqTpxNj9vO', TRUE) [23505-172]
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:474)
    at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:208)
    at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:49)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runScripts(DataSourceInitializer.java:135)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runDataScripts(DataSourceInitializer.java:95)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.onApplicationEvent(DataSourceInitializer.java:88)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.onApplicationEvent(DataSourceInitializer.java:46)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:98)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:333)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runSchemaScripts(DataSourceInitializer.java:78)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.initialize(DataSourceInitializer.java:71)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:349)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:300)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)
使用这些用户帐户为安全数据库表种子的最佳方法是什么?我尝试使用代码,但无法使加载程序以正确的顺序工作

更新: 当我逐步遍历ResourceDatabasePopulator.populate时,我看到有两个schema.sql实例正在使用。它们是:

file:.../out/test/OFAC/schema.sql
file:.../out/production/OFAC/schema.sql
我还有:

file:.../out/test/OFAC/data.sql
file:.../out/production/OFAC/data.sql

显然,使用重复的schema.sql没有什么坏处。但在ScriptUtils.executeSqlScript中,我看到两个data.sql文件也被调用。因此,我不明白为什么同时执行测试和生产sql文件。

看起来您在插入记录时没有提供主键

同样,一旦您解决了这个问题,您将面临另一个问题:您可以使用schema.sql或spring.jpa.hibernate.ddl auto=createdrop,但不能同时使用两者。如果需要,除了create drop之外,您还可以对DML插入使用data.sql,然后您可以让Hibernate创建表,并设置主键的自动生成(如果您需要的话)


顺便说一句:Boot 1.1.1.RELEASE位于Maven Central,请使用。

Dave,感谢您的反馈。我很确定我已经为H2表定义了主键,除非语法错误。因为我只插入了一条唯一的记录,所以我不明白为什么会失败。我删除了schema.sql,让Hibernate负责生成,并将insert语句放入我的data.sql中。这似乎合乎逻辑。但是,当我删除schema.sql并使用spring.jpa.hibernate.ddl auto=create-drop时,我得到了表not-found异常。您使用的是Boot 1.1.1吗?是的,当我使用schema.sql、data.sql和spring.jpa.hibernate.ddl auto=none时,我切换到了springBootVersion='1.1.1.1.RELEASE',,然后我又回到了唯一密钥冲突。如果我使用spring.jpa.hibernate.ddl auto=create drop并删除schema.sql,那么我就找不到表。我更新了我的问题,发现duplicate data.sql显然是罪魁祸首。但是我不知道如何解决这个问题,看起来您的构建工具正在创建重复的类路径?我想你需要拨回一点,然后尝试一个非常简单的构建配置。