springmvc与spring安全集成

zed5wv10  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(313)

我正试图在我的项目中增加安全性。我已经从网上找到了一个样本,但我无法实现正确的整合。
在我的依赖之下,

<properties>
        <java-version>1.8</java-version>
        <org.springframework-version>5.2.9.RELEASE</org.springframework-version>
        <org.hibernate-validator-version>5.4.1.Final</org.hibernate-validator-version>
        <org.hibernate-core-version>5.3.7.Final</org.hibernate-core-version>
        <c3p0-version>0.9.5.2</c3p0-version>
        <mysql-version>5.1.47</mysql-version>
        <spring.version>5.4.1</spring.version>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <!-- Spring MVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <!-- Spring ORM -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <!-- Hibernate Validator -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>${org.hibernate-validator-version}</version>
        </dependency>
        <!-- Hibernate Core Libs -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${org.hibernate-core-version}</version>
        </dependency>
        <!-- C3P0 Libs -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>${c3p0-version}</version>
        </dependency>
        <!-- MySQL JDBC Lib -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-version}</version>
        </dependency>
        <!-- JSTL Libs -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!-- Tag Libs -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- JSP Libs -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- Spring Security Core -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring Security Config -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring Security Web -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.4.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
        <dependency>
           <groupId>commons-beanutils</groupId>
           <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
       </dependency>                
       <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>2.0.1.Final</version>
        </dependency>  
    </dependencies>

项目结构
我的应用程序上下文,

import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@PropertySource("classpath:database.properties")
@EnableTransactionManagement
public class AppContextX {

    @Autowired
    private Environment environmentX;

    @Bean
    public LocalSessionFactoryBean XSessionFactory() {
        LocalSessionFactoryBean sessionFactoryX = new LocalSessionFactoryBean();
        sessionFactoryX.setDataSource(dataSource());
        sessionFactoryX.setPackagesToScan(new String[] {"com.mutfakapp.xmutfak.entity"});
        sessionFactoryX.setHibernateProperties(XHibernateProperties());
        return sessionFactoryX;
    }

    private Properties XHibernateProperties() {
        Properties propertiesX = new Properties();
        propertiesX.put("hibernate.dialect", environmentX.getRequiredProperty("hibernate.dialect"));
        propertiesX.put("hibernate.show_sql",environmentX.getRequiredProperty("hibernate.show_sql"));
        propertiesX.put("hibernate.format_sql", environmentX.getRequiredProperty("hibernate.format_sql"));
        propertiesX.put("hibernate.hbm2ddl.auto", environmentX.getRequiredProperty("hibernate.hbm2ddl"));
        return propertiesX;
    }

    private DataSource dataSource() {
        DriverManagerDataSource dataSourceX = new DriverManagerDataSource();
        dataSourceX.setDriverClassName(environmentX.getRequiredProperty("jdbc.driverClassName"));
        dataSourceX.setUrl(environmentX.getRequiredProperty("jdbc.url"));
        dataSourceX.setUsername(environmentX.getRequiredProperty("jdbc.username"));
        dataSourceX.setPassword(environmentX.getRequiredProperty("jdbc.password"));
        return dataSourceX;
    }

    @Bean
    public HibernateTransactionManager getTransactionManager() {
        HibernateTransactionManager transactionManagerX = new HibernateTransactionManager();
        transactionManagerX.setSessionFactory(XSessionFactory().getObject());
        return transactionManagerX;
    }
}

数据库属性,


# JDBC

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/testdb?useSSL=false
jdbc.username=root
jdbc.password=123

# Hibernate

hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl=update

我的应用初始化程序,

package com.mutfakapp.xmutfak.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializerX extends AbstractAnnotationConfigDispatcherServletInitializer
{

    @Override
    protected Class<?>[] getRootConfigClasses() {

        return new Class[] {AppContextX.class};

    }

    @Override
    protected Class<?>[] getServletConfigClasses() {

        return new Class[] {WebMvcConfigX.class};

    }

    @Override
    protected String[] getServletMappings() {

        return new String[] { "/" };
    }

}

WebMVC配置如下,

package com.mutfakapp.xmutfak.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebSecurity
@EnableWebMvc
@ComponentScan(basePackages = {"com.mutfakapp.xmutfak"})
@Import({ WebSecurityConfig.class })
public class WebMvcConfigX implements WebMvcConfigurer {

    @Bean
    public InternalResourceViewResolver XResolver() {
        InternalResourceViewResolver resolverX = new InternalResourceViewResolver();
        resolverX.setViewClass(JstlView.class);
        resolverX.setPrefix("/WEB-INF/views/");
        resolverX.setSuffix(".jsp");
        return resolverX;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

}

和web安全配置

package com.mutfakapp.xmutfak.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.mutfakapp.xmutfak.service.UserService;

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers(
                "/",
                "/home",
                "/lunch",
                "/dinner",
                "/registration").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin().defaultSuccessUrl("/addreceipt")
            .loginPage("/login")
            .permitAll()
            .and()
            .logout()
            .invalidateHttpSession(true)
            .clearAuthentication(true)
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login?logout")
            .permitAll();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
        auth.setUserDetailsService(userService);
        auth.setPasswordEncoder(passwordEncoder());
        return auth;
    }
}

当我运行该项目时,我得到以下错误。我想不通。

SEVERE: Exception starting filter [springSecurityFilterChain]
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:816)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1115)
    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:338)
    at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:243)
    at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:239)
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:270)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:106)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4566)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5203)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:843)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:772)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
d7v8vwbk

d7v8vwbk1#

我了解到您在spring是新手,您尝试使用springmvc和springsecurity准备简单的helloworld项目。如果是这样,我建议使用Spring Boot。它为spring项目提供了自动配置。
您可以使用spring初始化器生成项目。只需添加所需的依赖项:SpringWeb-mvc和SpringSecurity。我看到您在使用hibernate—将此orm与spring应用程序结合使用的最简单方法是使用spring数据jpa。您还需要数据库连接的jdbc驱动程序(这里是mysql)。

在那之后,你可以下载你的应用程序-它准备好了。您应该在src/main/resources/application.properties文件中定义访问数据库的属性:

spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=123
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=update

您还应该使用secutiry配置创建类。

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/hello").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }
}

简单控制器:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    @GetMapping(value = {"/", "/hello"})
    public String hello() {
        return "Hello";
    }

    @GetMapping("/secret")
    public String secret() {
        return "Only for signed in users";
    }
}

启动应用程序时,您会看到为用户生成的密码:

Using generated security password: 609ebedd-605e-4045-b6fd-5930b53720a2

你什么时候去localhost:8080:hello您将看到消息“hello”。你什么时候去localhost:8080/secret 禁止进入。你必须用生成的密码以“用户”身份登录。
在本例中,我只与数据库连接,但我不使用它-就像您在应用程序中使用它一样。
如果要查看是否已连接到数据库创建实体:

@Entity
class Car {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String name;

//plus getters, setters, equals, hashCode
}

和存储库:

interface CarRepository extends JpaRepository<Car, Long> {
}

数据库中的表将在应用程序启动时创建。

相关问题