【问题标题】:Spring Security JDBC authentication default schema error when using PostgreSQL使用 PostgreSQL 时 Spring Security JDBC 身份验证默认模式错误
【发布时间】:2014-08-02 05:11:56
【问题描述】:

Spring Security 和 PostgreSQL 真的不能使用 default schema,因为 "varchar_ignorecase" does not exist 部分无法替换吗?

我只是在测试默认设置:

auth.jdbcAuthentication()
            .dataSource(dataSource)
            .withDefaultSchema();

以下是错误:

原因:
org.springframework.beans.factory.BeanDefinitionStoreException: 工厂方法 [public javax.servlet.Filter org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain() throws java.lang.Exception] 抛出异常;

嵌套异常是
org.springframework.jdbc.datasource.init.ScriptStatementFailedException: 资源类第 1 行 SQL 脚本语句执行失败 路径资源
[org/springframework/security/core/userdetails/jdbc/users.ddl]:创建 表用户(用户名 varchar_ignorecase(50)不为空主要 键,密码 varchar_ignorecase(500) 不为空,启用布尔值不 空值);

嵌套异常是
org.postgresql.util.PSQLException:错误: 类型“varchar_ignorecase”不存在

【问题讨论】:

    标签: spring spring-security postgresql-9.1


    【解决方案1】:

    由于默认的schema不适合PostgreSQL,我需要自己创建schema并实现自己的用户查询和权限查询。

    auth.jdbcAuthentication()
                    .dataSource(dataSource)
                    .usersByUsernameQuery(
                            "select username,password, enabled from users where username=?")
                    .authoritiesByUsernameQuery(
                            "select username, role from user_roles where username=?");
    

    【讨论】:

    • 为什么架构“不适合”PostgreSQL 和 MySQL?顺便说一句,它正在工作...... tks
    • @Hinotori 默认模式(根据docs.spring.io/spring-security/site/docs/current/reference/html/…)是用 HSQLDB 的 SQL 方言编写的(特别是,PostgreSQL 没有默认用户模式中存在的 'varchar_ignorecase' 类型)。其他数据库的用户需要将其转换为有效的东西。请参阅此处有关使用 Spring JDBC 初始化数据库的文档,它有一些很好的提示:docs.spring.io/spring-boot/docs/current/reference/html/…
    • 我已经按照上面说的做了,它仍然执行 ddl。
    • 为避免dll 执行,您必须删除withDefaultSchema() 语句
    • @ManuelJordan 这里已经是午夜了……我今天在这上面花了 4 个小时。感谢您的评论!
    【解决方案2】:

    无需添加 withDefaultSchema()。只需使用正确的列名和外键约束定义您的 schema.sql 和 data.sql。以下是 Mysql 的示例配置(在 Spring Boot 中)。

    schema.sql

    DROP TABLE IF EXISTS users;
    DROP TABLE IF EXISTS authorities;
    
    CREATE TABLE users
    (
       username VARCHAR(50)  NOT NULL,
       password VARCHAR(100) NOT NULL,
       enabled  TINYINT      NOT NULL DEFAULT 1,
       PRIMARY KEY (username)
     );
    
    CREATE TABLE authorities
    (
    username  VARCHAR(50) NOT NULL,
    authority VARCHAR(50) NOT NULL,
    FOREIGN KEY (username) REFERENCES users (username)
    );
    

    然后定义用户和权限(data.sql)

    INSERT INTO users (username, password, enabled)
    values ('user','pass',1);
    
    INSERT INTO authorities (username, authority)
    values ('user', 'ROLE_USER');
    

    最后,定义认证机制

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .jdbcAuthentication()
                .passwordEncoder(NoOpPasswordEncoder.getInstance())
                .dataSource(dataSource);
    }
    

    【讨论】:

      【解决方案3】:

      PGSQL 架构:

      schema.sql

      DROP TABLE IF EXISTS users;
      DROP TABLE IF EXISTS authorities;
      
      CREATE TABLE users
      (
      username VARCHAR(50)  NOT NULL,
      password VARCHAR(100) NOT NULL,
      enabled  INT      NOT NULL DEFAULT 1,
      PRIMARY KEY (username)
      );
      
      CREATE TABLE authorities
      (
      username  VARCHAR(50) NOT NULL,
      authority VARCHAR(50) NOT NULL,
      FOREIGN KEY (username) REFERENCES users (username)
      );
      

      data.sql 上的用户注入

      INSERT INTO users (username, password, enabled)
      values ('user','pass',1);
      
      INSERT INTO authorities (username, authority)
      values ('user', 'ROLE_USER');
      

      感谢Q先生。我完全使用了您的 MySQL 架构并将其改编为 PGSQL。

      【讨论】:

        猜你喜欢
        • 2015-08-13
        • 2020-08-06
        • 1970-01-01
        • 1970-01-01
        • 2020-04-08
        • 1970-01-01
        • 2016-08-15
        • 2011-11-14
        • 2018-07-30
        相关资源
        最近更新 更多