简体   繁体   English

Spring Security从XML配置到Java配置

[英]Spring security from xml configuration to java config

This was my security xml configuration. 这是我的安全性xml配置。

    <?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd">

    <http auto-config="true">
        <csrf disabled="true"/>
        <intercept-url pattern="/" access="hasRole('ROLE_USER')"/>
        <intercept-url pattern="/welcome" access="hasRole('ROLE_USER')"/>
        <form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/login?error"
                    username-parameter="username" password-parameter="password"/>
        <logout logout-success-url="/login?logout"/>
    </http>

    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="userDetailsServiceImpl">
            <password-encoder ref="encoder"/>
        </authentication-provider>
    </authentication-manager>

    <beans:bean id="userDetailsServiceImpl" class="com.egs.account.service.user.UserDetailsServiceImpl"/>

    <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
        <beans:constructor-arg name="strength" value="11"/>
    </beans:bean>
</beans:beans>

And this one was my web.xml file. 这是我的web.xml文件。

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <display-name>Account Registration Web Application</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/resources/appconfig-root.xml</param-value>
    </context-param>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value/>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

Now I have switched to Java config, and those Config classes are the equivalent versions of my web.xml and security.xml files. 现在,我切换到Java config,这些Config类是我的web.xml和security.xml文件的等效版本。

@Configuration
@EnableWebSecurity
@ComponentScan("com.egs.account.*")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authProvider())
                .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/welcome**").access("hasRole('USER')")
                .and().formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/welcome")
                .failureUrl("/login?error");

        http.csrf().disable();
    }

    @Autowired
    public DaoAuthenticationProvider authProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsServiceImpl());
        authProvider.setPasswordEncoder(bCryptPasswordEncoder());

        return authProvider;
    }

    @Bean
    public PasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder(11);
    }

    @Autowired
    public UserDetailsService userDetailsServiceImpl() {
        return new UserDetailsServiceImpl();
    }
}

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(SecurityConfiguration.class);
    }

}


@Configuration
@PropertySource(value = "classpath:application.properties")
@ComponentScan(basePackages = {"com.egs.account.*"})
@Import({SecurityConfiguration.class, MvcConfig.class})
public class SpringWebAppInitializer implements WebApplicationInitializer {

    @Autowired
    Environment env;

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
        appContext.register(MvcConfig.class);
        appContext.setServletContext(servletContext);
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
                "dispatcher", new DispatcherServlet(appContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

And when I run the application, I get such exception. 当我运行该应用程序时,会出现此类异常。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'securityService': Error creating bean with name 'securityServiceImpl': Unsatisfied dependency expressed through field 'authenticationManager': No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency [org.springframework.security.authentication.AuthenticationManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency [org.springframework.security.authentication.AuthenticationManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityServiceImpl': Unsatisfied dependency expressed through field 'authenticationManager': No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency [org.springframework.security.authentication.AuthenticationManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency [org.springframework.security.authentication.AuthenticationManager]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

This part of my UserController. 我的UserController的这一部分。

@Controller
public class UserController {

    private UserService userService;

    @Autowired
    private CatalogService catalogService;

    @Autowired
    private SecurityService securityService;
}

And this one is my SecurityServiceImpl 这是我的SecurityServiceImpl

@Service("securityServiceImpl")
public class SecurityServiceImpl implements SecurityService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class);

    @Override
    public String findLoggedInUsername() {
        Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails();
        if (userDetails instanceof UserDetails) {
            return ((UserDetails) userDetails).getUsername();
        }

        return null;
    }

    @Override
    public void autoLogin(String username, String password) {
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());

        authenticationManager.authenticate(usernamePasswordAuthenticationToken);

        if (usernamePasswordAuthenticationToken.isAuthenticated()) {
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            logger.debug(String.format("Auto login %s successfully!", username));
        }
    }
}

Who can tell me what else I have forgotten to add, as I got such terrible exception. 谁能告诉我我忘记添加了什么,因为我遇到了如此可怕的例外。

Replace @Autowired with @Bean on top of 在顶部将@Autowired替换为@Bean

public DaoAuthenticationProvider authProvider()

in SecurityConfiguration.java 在SecurityConfiguration.java中

Because of no bean for AuthenticationManager you got that exception. 由于没有用于AuthenticationManager的bean,您得到了该异常。

The issue looks like - 问题看起来像-

        auth.authenticationProvider(authProvider())
            .inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");

You are mixing a memoryRealm with your authProvider() - but dont use a memoryRealm in your xml? 您正在将memoryRealm与authProvider()混合使用-但不要在xml中使用memoryRealm? Can you try stripping this back to use a memoryRealm to confirm you can create a authentication manager 您是否可以尝试将其剥离回去以使用内存?Realm确认您可以创建身份验证管理器

I would expect it to be something like - 我希望它像-

auth.authenticationProvider(authProvider())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM