defining bean for custom userdetailsservice

后端 未结 1 953
走了就别回头了
走了就别回头了 2021-01-17 00:27

How can I define my custom UserDetailsService bean in a way that enables my spring mvc web app to use my underlying MySQL database to check authenticati

相关标签:
1条回答
  • 2021-01-17 01:02

    To summarize comments, here's the answer.

    There are several things wrong here:

    1) When mixing XML configuration and Java configuration in Spring in a way that java config is imported inside xml config file, <context:annotation-config/> needs to be present in xml file and java config class needs to be declared as a bean. <context:annotation-config/> will enable annotation processing of the declared bean and @Configuration annotation will then be processed. Read more at the documentation: http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-java-combining

    To fix te problem insert <context:annotation-config/> in business-config.xml. <context:annotation-config/> is needed for <bean class="org.springframework.security.samples.petclinic.config.SecurityConfig"></bean> to work so they need to be declared in the same bean profile.

    2) You are autowiring a concrete class (CustomUserDetailsSerivce) in SpringConfig instead of an interface (UserDetailsService). While it's possible to use Spring to autowire concrete classes usually it's better to autowire to interfaces (Spring will autowire concreate CustomUserDetailsSerivce implementation to @Autowired UserDetailsService field). Spring creates proxies around wired classes to enable certain features (such as declarative transactions) and such proxies may easily implement an interface when autowiring but may fail if attempted to be autowired to a concrete class. It is possible though to achieve it - more information here: Spring Autowiring class vs. interface? In this case, it's definitely better to autowire to UserDetailsService interface since that is what our security config actually depends on.

    To fix this issue specify field type as UserDetailsService in SpringConfig:

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

    3) You seem to be setting up both jdbc authentication and authentication using a custom user details service. Spring JDBC authentication is usually used if you want Spring Security to use jdbc to query a database and find about existing users and their roles etc... Custom UserDetailsSerivce is used if you want implement querying for users/roles etc... your self. In your example (since you are providing your custom UserDetailsService which will query the backend using ClinicService) you don't need JDBC authentication.

    Here's an example of working spring security configuration that uses custom UserDetailsService (implemented elsewhere and autowired by spring) via java config:

    @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);
        }
    }
    

    I suggest reading the actual documentation as it describes what specific configuration builder methods do and provide the examples: 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 - added login form configuration and link to documentation

    EDIT 2 - added more explanations for problem 1)

    EDIT 3 - changed role name form "ADMIN" to "ROLE_ADMiN" to match role names in UserDetailsService

    0 讨论(0)
提交回复
热议问题