Spring Security: преобразование аутентификации в памяти в базу данных - PullRequest
1 голос
/ 01 апреля 2020

Я использую аутентификацию в памяти, чтобы мой логин работал весной

Однако я хочу изменить его сейчас на постоянную базу данных

Пожалуйста, см. Код ниже:

JWTWebSecurityConfig

package com.sbc.cpex.security.jwt;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

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

    @Autowired
    private JwtUnAuthorizedResponseAuthenticationEntryPoint jwtUnAuthorizedResponseAuthenticationEntryPoint;

    @Autowired
    private UserDetailsService jwtInMemoryUserDetailsService;

    @Autowired
    private JwtTokenAuthorizationOncePerRequestFilter jwtAuthenticationTokenFilter;

    @Value("${jwt.get.token.uri}")
    private String authenticationPath;

    @Autowired
    DataSource dataSource;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

//      auth
//            .userDetailsService(jwtInMemoryUserDetailsService)
//            .passwordEncoder(passwordEncoderBean());

        auth.jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery("select username, password"
            + " from users where username=?")
        .passwordEncoder(passwordEncoderBean());
    }

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

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
            .csrf().disable()
//            .csrf().and().cors().disable()
            .exceptionHandling().authenticationEntryPoint(jwtUnAuthorizedResponseAuthenticationEntryPoint).and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .authorizeRequests()
            .anyRequest().authenticated();

       httpSecurity
            .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        httpSecurity
            .headers()
            .frameOptions().sameOrigin()  //H2 Console Needs this setting
            .cacheControl(); //disable caching
    }

    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity
            .ignoring()
            .antMatchers(
                HttpMethod.POST,
                authenticationPath
            )
            .antMatchers(HttpMethod.OPTIONS, "/**")
            .and()
            .ignoring()
            .antMatchers(
                HttpMethod.GET,
                "/" //Other Stuff You want to Ignore
            )
            .and()
            .ignoring()
            .antMatchers("/h2-console/**/**");//Should not be in Production!
    }
}

Шаги, которые я сделал: 1. Закомментируйте эти строки

auth
    .userDetailsService(jwtInMemoryUserDetailsService)
    .passwordEncoder(passwordEncoderBean());
Добавьте следующие строки для jdbcauth
auth.jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery("select username, password"
            + " from users where username=?")
        .passwordEncoder(passwordEncoderBean());
Создайте класс с именем DataSourceConfig
package com.sbc.cpex.security.jwt;

import javax.sql.DataSource;

import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DataSourceConfig {

    @Bean
    public DataSource getDataSource() {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); 
        dataSourceBuilder.username("test"); 
        dataSourceBuilder.password("pass"); 
        return dataSourceBuilder.build(); 
    }
}

Но я получаю эту ошибку

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'h2Console' defined in class path resource [org/springframework/boot/autoconfigure/h2/H2ConsoleAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'h2Console' threw exception; nested exception is java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.

Пожалуйста, просветите меня. ТИА

1 Ответ

1 голос
/ 01 апреля 2020

Трассировка стека сама по себе не требует пояснений:

nested exception is java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.

Вам необходимо предоставить URL источника данных при создании компонента источника данных. По трассировке стека я понял, что вы используете H2. Таким образом, вы можете создать bean-компонент типа:

@Bean
public DataSource getDataSource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
    dataSourceBuilder.driverClassName("org.h2.Driver");
    dataSourceBuilder.url("jdbc:h2:mem:test");
    dataSourceBuilder.username("username");
    dataSourceBuilder.password("");
    return dataSourceBuilder.build();
}

. В своем коде вы указали только часть имени пользователя и пароля, поэтому он выдает ошибку.

@ iamjpcbau Springboot - это автоконфигурирование H2 в качестве базы данных, поскольку он находится в качестве зависимости во время сканирования пути класса. Поскольку вы предоставили bean-компонент Datasource, Spring автоматически принимает его для настройки H2, но URL-адрес отсутствует, что вызывает исключение, которое вы получаете.

Inorder для настройки другой базы данных с вашим проектом, настройте базу данных через application.properties или application.yml или вручную создайте компоненты конфигурации, чтобы конфигурация для вашей соответствующей базы данных использовалась при запуске вместо H2.Now, поскольку нет другой настроенной базы данных, и поскольку H2 найден в classpath, Spring настраивает это по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...