2014-03-30 81 views
0

如何以我的spring mvc web應用程序使用我的基礎MySQL數據庫檢查用戶和密碼驗證的方式定義我的自定義UserDetailsService bean?爲自定義userdetails服務定義bean

以下是具體情況:

我加入安全的spring petclinic樣品瞭解春季安全的一種方式。我正在使用Java配置,並且已經創建了一個SecurityConfig.java文件,它擴展了WebSecurityConfigurerAdapter。我試圖設置JdbcAuthentication,該方式利用內置於petclinic樣本中的由ClinicService工具管理的MySQL數據庫。因此,我創建了一個CustomUserDetailsService類延伸UserDetailsService,並且其intented到SecurityConfig.javaClinicService.java鏈接。我創建了一個User類和Role類的usersroles表,分別模擬在MySQL數據庫。

我加入以下行business-config.xml定義CustomUserDetailService

<bean class="org.springframework.samples.petclinic.service.CustomUserDetailsService"></bean> 

但尚未我仍然得到以下錯誤,指出爲CustomUserDetailService豆尚未定義:

Caused by: java.lang.IllegalArgumentException: Can not set 
org.springframework.samples.petclinic.service.CustomUserDetailsService field 
org.springframework.security.samples.petclinic.config.SecurityConfig.myCustomUserDetailsService 
to $Proxy61 

爲了保持這篇文章的簡潔,我已經將相關備份材料加載到文件共享網站。您可以點擊以下鏈接閱讀所有源代碼和完整的堆棧跟蹤:

您可以閱讀SecurityConfig.javaby clicking on this link
business-config.xml的代碼是at this link
CustomUserDetailService.java的代碼是at this link
User實體的代碼是at this link
Role實體的代碼是at this link
完整的堆棧跟蹤可以被讀取at this link

所有應用程序的其他代碼可以在爲Spring PetClinic示例,它可以讀取by clicking on this link GitHub的頁面上找到。

這裏是a link to the code for login.jsp

這裏是a link to my revised business-config.xml code

+0

匹配角色名稱好像你的java的配置風格的配置不檢測XML配置定義的bean。看看http://stackoverflow.com/questions/13254779/how-to-import-java-config-class-into-xml-config-so-that-both-contexts-have-beans並嘗試添加'< context:annotation-config />'到xml配置,看看它是否有幫助。 –

+0

我會在business-config.xml中的第一個''下面添加它 –

+0

您應該在SecurityConfig中指定一個接口作爲依賴項,並讓spring容器自動調用一個實現 - 將CustomUserDetailsS​​ervice更改爲UserDetailsS​​ervice。另外,如果您打算使用自定義的UserDetailsS​​ervice執行身份驗證和授權(例如,如果用戶不存在,則爲您的UserDetailsS​​ervice拋出UsernameNotFoundException),則不需要jdbc身份驗證。 –

回答

4

總結評論,這裏是答案。

錯在這裏有幾件事情:

1)的方式,java的配置,那麼內部的XML配置文件,<context:annotation-config/>需要存在於XML文件和Java配置進口混合XML的配置和Java配置在Spring類需要被聲明爲一個bean。 <context:annotation-config/>將啓用聲明bean的註釋處理,然後處理@Configuration註釋。閱讀文檔更多信息:http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-java-combining

修復在business-config.xml中插入<context:annotation-config/>問題。 <bean class="org.springframework.security.samples.petclinic.config.SecurityConfig"></bean>需要<context:annotation-config/>才能工作,因此需要在同一個bean配置文件中聲明它們。

2)您在SpringConfig中自動裝配具體類(CustomUserDetailsS​​erivce)而不是接口(UserDetailsS​​ervice)。雖然可以使用Spring來自動調用具體類,但通常最好是自動調用接口(Spring會自動調用CustomUserDetailsS​​erivce實現到@Autowired UserDetailsS​​ervice字段)。 Spring在有線類周圍創建代理來啓用某些功能(如聲明性事務),並且此類代理在自動裝配時可以輕鬆實現接口,但如果嘗試自動裝配到具體類時可能會失敗。有可能實現它 - 更多信息在這裏:Spring Autowiring class vs. interface? 在這種情況下,自動裝入UserDetailsS​​ervice接口肯定會更好,因爲這是我們的安全配置實際依賴的。

要解決此問題,指定字段類型的UserDetailsS​​ervice在SpringConfig:

//Use UseDetailsService interface as field type instead of concrete class CustomUserDao 
@Autowired 
private UserDetailsService myCustomUserDetailsService; 

3)你似乎使用自定義用戶詳細信息服務被設置了JDBC認證和認證。如果您希望Spring Security使用jdbc來查詢數據庫並查找現有用戶及其角色等,通常會使用Spring JDBC身份驗證。如果您想要爲用戶/角色等實現查詢,請使用自定義UserDetailsS​​erivce。在你的例子中(因爲你提供了自定義的UserDetailsS​​ervice,它將使用ClinicService來查詢後端),你不需要JDBC認證。

下面是通過Java配置使用自定義的UserDetailsS​​ervice(彈簧其它地方執行和自動裝配)工作彈簧安全配置的例子:

@Configuration 
@EnableWebMvcSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserDetailsService userDetailsService; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .formLogin() 
       .loginPage("/login") 
       .defaultSuccessUrl("/petclinic/") 
       .usernameParameter("j_username") // default is username 
       .passwordParameter("j_password") // default is password 
       .loginProcessingUrl("/j_spring_security_check") // default is /login with an HTTP post 
       .failureUrl("/login") 
       .permitAll() 
       .and() 
      .logout() 
       .logoutSuccessUrl("/index.jsp") 
       .and() 
      .authorizeRequests() 
       .antMatchers("/**").hasRole("ROLE_ADMIN") 
       .antMatchers("/j_spring_security_check").permitAll() 
       .and() 
      .userDetailsService(userDetailsService); 
    } 
} 

我建議您閱讀實際的文件,因爲它描述了具體的配置生成器方法做和提供的實施例:http://docs.spring.io/spring-security/site/docs/3.2.0.RC2/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html#formLogin()

EDIT 1 - 加入登錄表單配置,並鏈接到文檔

EDIT 2 - 加入更多的解釋針對問題1)

編輯3 - 更改角色名稱表「ADMIN」到「ROLE_ADMIN」中的UserDetailsS​​ervice

+0

向答案添加了附加解釋和代碼示例。 –

+0

登錄表單看起來不錯。要調試,我會在loadUserByUsername中設置調試器斷點,並查看它是否在登錄嘗試時執行,並驗證您返回的UserDetails是否包含您期望的值。此外,我們允許訪問所有人的登錄處理URL(請參閱編輯答案的addtional antMatcher。 –

+0

@CodeMed如果你擺脫了這個異常,並且你的UserDetailService被正確注入,你的問題就會得到解答。其餘的都是獎金。我認爲推動某人解決所有可能的問題直到你能接受他的答案是公平的。如果您在打印文本時遇到問題,請執行一些實際調試並在關鍵位置設置斷點並查看環境。 – Bart