Oracle + Spring Security身份验证:SQLException:列索引无效

时间:2011-05-13 18:28:25

标签: java oracle jdbc spring-security

我正在使用Spring MVC + Security和Oracle 10g。当我尝试验证时,我收到以下错误:

Error : PreparedStatementCallback; invalid ResultSet access for SQL [SELECT PAYGATEMANAGER.AUTHENTICATION_PKG.getUser(?) FROM DUAL]; nested exception is java.sql.SQLException: Invalid column index 

security.xml文件:

<authentication-manager>
    <authentication-provider>
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query=
                "SELECT PAYGATEMANAGER.AUTHENTICATION_PKG.getUser(?) FROM DUAL"
            authorities-by-username-query=
                "SELECT PAYGATEMANAGER.AUTHENTICATION_PKG.getAuthorities(?) FROM DUAL" />
    </authentication-provider>
</authentication-manager>

PL / SQL:

CREATE OR REPLACE PACKAGE PAYGATEMANAGER.AUTHENTICATION_PKG AS
TYPE T_REFCURSOR IS REF CURSOR;

  FUNCTION getUser(username IN VARCHAR2) RETURN T_REFCURSOR;  
  FUNCTION getAuthorities(username IN VARCHAR2) RETURN T_REFCURSOR;

END AUTHENTICATION_PKG;

CREATE OR REPLACE PACKAGE BODY PAYGATEMANAGER.AUTHENTICATION_PKG AS 

FUNCTION getUser(username IN VARCHAR2) 
    RETURN T_REFCURSOR IS
        userInfo T_REFCURSOR;
BEGIN

    OPEN userInfo FOR
    SELECT
        U.NAME AS username ,
        P.PASSWORD AS password,
        'true' AS enabled            
    FROM
        PAYGATEMANAGER.USERS U INNER JOIN PAYGATEMANAGER.PASSWORDS P
        USING(USER_ID)
    WHERE 
        U.NAME = username;

RETURN userInfo;
END;

FUNCTION getAuthorities(username IN VARCHAR2) 
    RETURN T_REFCURSOR IS
        userAuthorities T_REFCURSOR;
BEGIN

    OPEN userAuthorities FOR
    SELECT
        U.NAME AS username ,
        UR.ROLE AS authorities           
    FROM
        PAYGATEMANAGER.USERS U INNER JOIN PAYGATEMANAGER.USERS_ROLES UR
        USING(USER_ID)
    WHERE 
        U.NAME = username;

RETURN userAuthorities;
END;

END AUTHENTICATION_PKG;

我认为原因是返回类型为T_REFCURSOR,它没有获取用户名,密码,已启用。但是如何解决这个问题?要在将来添加一些功能(例如登录尝试审计),我想我应该在PL / SQL函数中执行它,而不是在SQL中进行硬编码。

1 个答案:

答案 0 :(得分:0)

这肯定不适用于“开箱即用”JdbcDaoImpl(这是<jdbc-user-service>映射到的)。我建议查看标准实现的源代码,然后编写自己的实现,实现Spring Security UserDetailsService,但使用JDBC和CallableStatement

您将实现类声明为常规spring bean:

 <bean id="MyPlsqlUserDetailsService" class="my.great.JdbcCallableStatementImpl"/>

...然后使用ref上的<user-details-service>属性,如下所示:

 <user-details-service ref="MyPlsqlUserDetailsService"/>

(请注意,我忽略了XML名称空间等的复杂性,希望您能理解这些内容)。

祝你好运!