2011-05-13 32 views
0

我使用的是Spring MVC +安全性和Oracle 10g。當我嘗試驗證我得到以下錯誤:Oracle + Spring安全認證:SQLException:列索引無效

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中進行硬編碼。

回答

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名稱空間的複雜等等,希望你能理解這些)。

祝你好運!

+0

是的,我明白。感謝您的幫助,我會盡力實施您的建議。 – Greg 2011-05-14 08:10:29

+0

我讀過你書中的一些章節。我認爲Spring Security中最完整的一本書幫助了我很多。謝謝! – Greg 2011-05-14 08:16:49

+0

謝謝!如果您想就此問題提出任何其他建議,請告知我們。 – 2011-05-16 16:41:07