开发者

Oracle+Spring Security Authentication: SQLException: Invalid column index

开发者 https://www.devze.com 2023-03-06 00:19 出处:网络
I\'m using Spring MVC+Security and Oracle 10g. When I try authenticate I get the following error: Error : PreparedStatementCallback; invalid ResultSet access for SQL [SELECT PAYGATEMANAGER.AUTHENTICA

I'm using Spring MVC+Security and Oracle 10g. When I try authenticate I get the following error:

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 PAYGA开发者_如何学运维TEMANAGER.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;

I think the reason is in return type T_REFCURSOR, which is not fetching into username, password, enabled. But how to fix this? To add some functionality in future (e.g. login attempts audit) I think I should do it in PL/SQL functions, not hard coding in SQL.


This definitely won't work with the "out of the box" JdbcDaoImpl (which is what <jdbc-user-service> maps to). I would suggest reviewing the source code of the standard implementation, and then writing your own implementation which implements the Spring Security UserDetailsService, but uses JDBC and CallableStatement under the covers.

You will declare your implementation class as a regular spring bean:

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

... and then use the ref attribute on <user-details-service> as follows:

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

(Note that I'm omitting the intricacy of XML namespaces etc etc, hopefully you understand those).

Good luck!

0

精彩评论

暂无评论...
验证码 换一张
取 消