Spring 安全查询无效列索引异常但在 Oracle 上工作
Spring Security query Invalid column index exception but working on Oracle
我正在使用 spring security 4,我输入的查询似乎不起作用,即使它在 PL/SQL.
中可以正常工作
我想访问 ROLETYPE
table。 table 与主键和外键链接,例如:UTILISATEURS
有 POSTES
有 ROLES
有 RHNOM
(角色类型 LIB1
)
查询如下:
authorities-by-username-query="select LIB1 from RHNOM rh, UTILISATEURS u, POSTES p, ROLES r
where u.IDPOSTE = p.ID_POSTE and p.ID_ROLE = r.ID_ROLE and r.ID_TYP_ROLE = rh.IDNOM and u.LOGIN = ?" />
错误:
Caused by: org.springframework.jdbc.InvalidResultSetAccessException: PreparedStatementCallback; invalid ResultSet access for SQL [select LIB1 from RHNOM rh, UTILISATEURS u, POSTES p, ROLES r where u.IDPOSTE = p.ID_POSTE and p.ID_ROLE = r.ID_ROLE and r.ID_TYP_ROLE = rh.IDNOM and u.LOGIN = ?]; nested exception is java.sql.SQLException: Index de colonne non valide
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:695)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:727)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:737)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:787)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.loadUserAuthorities(JdbcDaoImpl.java:236)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.loadUserByUsername(JdbcDaoImpl.java:188)
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:114)
... 34 more
Caused by: java.sql.SQLException: Index de colonne non valide
at oracle.jdbc.driver.OracleResultSetImpl.getString(OracleResultSetImpl.java:1277)
at org.apache.commons.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:213)
at org.apache.commons.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:213)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.mapRow(JdbcDaoImpl.java:240)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.mapRow(JdbcDaoImpl.java:237)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:60)
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:708)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:644)
... 41 more
您需要匹配 Spring 安全性期望的所有列,对于 authorities-by-username-query
是 username, authority
,请参阅 <jdbc-user-service>
和检索的实现:
protected List<GrantedAuthority> loadUserAuthorities(String username) {
return getJdbcTemplate().query(this.authoritiesByUsernameQuery,
new String[] { username }, new RowMapper<GrantedAuthority>() {
@Override
public GrantedAuthority mapRow(ResultSet rs, int rowNum)
throws SQLException {
String roleName = JdbcDaoImpl.this.rolePrefix + rs.getString(2);
return new SimpleGrantedAuthority(roleName);
}
});
}
来自 JdbcDaoImpl
in Spring Security 4.2.18.
如您所见,您实际上不需要第一列是用户名(因为它未被检索),但角色(权限)必须是第二列,因为它是通过索引检索的。
简而言之,您需要将查询更改为:
select u.LOGIN, LIB1 from ...
我正在使用 spring security 4,我输入的查询似乎不起作用,即使它在 PL/SQL.
中可以正常工作我想访问 ROLETYPE
table。 table 与主键和外键链接,例如:UTILISATEURS
有 POSTES
有 ROLES
有 RHNOM
(角色类型 LIB1
)
查询如下:
authorities-by-username-query="select LIB1 from RHNOM rh, UTILISATEURS u, POSTES p, ROLES r
where u.IDPOSTE = p.ID_POSTE and p.ID_ROLE = r.ID_ROLE and r.ID_TYP_ROLE = rh.IDNOM and u.LOGIN = ?" />
错误:
Caused by: org.springframework.jdbc.InvalidResultSetAccessException: PreparedStatementCallback; invalid ResultSet access for SQL [select LIB1 from RHNOM rh, UTILISATEURS u, POSTES p, ROLES r where u.IDPOSTE = p.ID_POSTE and p.ID_ROLE = r.ID_ROLE and r.ID_TYP_ROLE = rh.IDNOM and u.LOGIN = ?]; nested exception is java.sql.SQLException: Index de colonne non valide
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:695)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:727)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:737)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:787)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.loadUserAuthorities(JdbcDaoImpl.java:236)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.loadUserByUsername(JdbcDaoImpl.java:188)
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:114)
... 34 more
Caused by: java.sql.SQLException: Index de colonne non valide
at oracle.jdbc.driver.OracleResultSetImpl.getString(OracleResultSetImpl.java:1277)
at org.apache.commons.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:213)
at org.apache.commons.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:213)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.mapRow(JdbcDaoImpl.java:240)
at org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl.mapRow(JdbcDaoImpl.java:237)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:60)
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:708)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:644)
... 41 more
您需要匹配 Spring 安全性期望的所有列,对于 authorities-by-username-query
是 username, authority
,请参阅 <jdbc-user-service>
和检索的实现:
protected List<GrantedAuthority> loadUserAuthorities(String username) { return getJdbcTemplate().query(this.authoritiesByUsernameQuery, new String[] { username }, new RowMapper<GrantedAuthority>() { @Override public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException { String roleName = JdbcDaoImpl.this.rolePrefix + rs.getString(2); return new SimpleGrantedAuthority(roleName); } }); }
来自 JdbcDaoImpl
in Spring Security 4.2.18.
如您所见,您实际上不需要第一列是用户名(因为它未被检索),但角色(权限)必须是第二列,因为它是通过索引检索的。
简而言之,您需要将查询更改为:
select u.LOGIN, LIB1 from ...