Spring security 使用Cassandra身份验证的Spring安全性失败
我正在尝试使用spring security和Cassandra数据库对用户进行身份验证。我遇到了以下异常:Spring security 使用Cassandra身份验证的Spring安全性失败,spring-security,cassandra,Spring Security,Cassandra,我正在尝试使用spring security和Cassandra数据库对用户进行身份验证。我遇到了以下异常: Authentication Failed: PreparedStatementCallback; bad SQL grammar [select userName, password from user where userName=?]; nested exception is java.sql.SQLSyntaxErrorException: No indexed colum
Authentication Failed: PreparedStatementCallback; bad SQL grammar [select userName, password from user where userName=?];
nested exception is java.sql.SQLSyntaxErrorException:
No indexed columns present in by-columns clause with "equals" operator 'select userName, password from user where userName=?'
以下是配置详细信息:
security-config.xml
<form-login
login-processing-url="/j_spring_security_check"
login-page="/index.xhtml" always-use-default-target="true"
authentication-failure-url="/index.xhtml?error=true"
authentication-success-handler-ref="authenticationSuccessHandler"
authentication-failure-handler-ref="authenticationFailureHandler"/>
<authentication-manager alias="authenticationManager">
<authentication-provider>
<jdbc-user-service data-source-ref="cassandraDataSource" users-by-username-query="select userName, password from user where userName=?"
authorities-by-username-query="select roleId, userName, roleName from role where userName=?"/>
</authentication-provider>
</authentication-manager>
desc mykeyspaces的结果
CREATE TABLE role (
roleid int PRIMARY KEY,
rolename text,
username text
) WITH bloom_filter_fp_chance = 0.01
AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
AND comment = ''
AND compaction = {'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32'}
AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = '99.0PERCENTILE';
CREATE INDEX userName_index ON role (username);
CREATE TABLE user (
userid int PRIMARY KEY,
email text,
firstname text,
lastname text,
password text,
phone int,
username text
) WITH bloom_filter_fp_chance = 0.01
AND caching = '{"keys":"ALL", "rows_per_partition":"NONE"}'
AND comment = ''
AND compaction = {'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32'}
AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = '99.0PERCENTILE';
CREATE INDEX userNameUser_index ON user (username);
cqlsh:system>
如果使用
user
和role
表进行安全保护,username
应该是这两个表上的分区键。仅仅对它们进行索引将导致查询多个节点,而不会有效。下面的数据模型将对您的查询更有效
CREATE TABLE user (
userid int,
email text,
firstname text,
lastname text,
password text,
phone int,
username text,
PRIMARY KEY ((username), userid)
)
CREATE TABLE role (
roleid int,
rolename text,
username text,
PRIMARY KEY ((username), roleid)
)
如您所见,主键由2列组成,以确保唯一性,但只有第一列是分区键。这可以确保该用户的所有记录都位于一个节点上,并且按用户名进行的查询将有效
关于Cassandra的数据建模有很多可用的方法,这与关系数据库的数据建模有很大不同。基本规则是:
- 了解分区和集群密钥
- 为查询建模,而不是为数据建模
- 索引不是有效的
选择用户名,从用户名=?0的用户选择密码。如果这无济于事,请考虑提出一个新问题。
CREATE TABLE user (
userid int,
email text,
firstname text,
lastname text,
password text,
phone int,
username text,
PRIMARY KEY ((username), userid)
)
CREATE TABLE role (
roleid int,
rolename text,
username text,
PRIMARY KEY ((username), roleid)
)