Метод SpringBoot UserDetailsService loadUserByUsername Никогда не вызывается с пользовательским WebSecurityConfigurerAdapter - PullRequest
1 голос
/ 07 марта 2020

Я следую инструкции в этом видео: https://www.youtube.com/watch?v=X80nJ5T7YpE&list=PLqq-6Pq4lTTYTEooakHchTGglSvkZAjnE&index=12

Мой код находится в состоянии отметки 7:30. По какой-то причине я не могу заставить класс SecurityConfigurer.java распознавать мой пользовательский класс UserDetailsService с именем MyUserDetailsService.java.

Ожидаемое поведение таково, что когда я go до конечной точки / hello, которую я указал в классе HelloResource.Java, должна быть сгенерирована страница входа. Я должен иметь возможность войти на веб-страницу с жестко закодированным возвращаемым значением User метода loadUserByUsername с именем пользователя и паролем "foo".

Независимо от того, какие изменения я делаю, всегда кажется, что loadUserByUsername метод не вызывается (я доказал это с помощью точек останова / операторов печати). Это наводит меня на мысль, что может быть какая-то проблема со сканированием компонентов, но мне еще предстоит увидеть, как что-то работает!

Я уже опробовал решения по следующим ссылкам: Один , Два , Три , плюс еще несколько. Вот мои соответствующие файлы:

JWTMain. java

package com.JWTTest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("{com.JWTTest}")
public class JwtMain {

    public static void main(String[] args) {
        SpringApplication.run(JwtMain.class, args);
    }
}

HelloResource. java

package com.JWTTest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloResource {

    @RequestMapping("/hello")
    public String HelloString(){
        return "Hello";
    }

}

MyUserDetailsService. java

package com.JWTTest;

import org.jvnet.hk2.annotations.Service;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;

@Service
public class MyUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new User("foo", "foo", true, true, true, true, new ArrayList<>());
    }
}

SecurityConfigurer. java

package com.JWTTest;

import org.apache.catalina.security.SecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
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.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@ComponentScan(basePackageClasses = MyUserDetailsService.class)
@EnableWebSecurity(debug = true)
@Import(value = {SecurityConfig.class})
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailsService myUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(myUserDetailsService);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}

application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/spring_security
spring.jpa.properties.hibernate.default_schema=users
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

build.gradle

plugins {
    id 'org.springframework.boot' version '2.2.1.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
    id 'java'
}

group = 'com.JWTTest'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}


dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-hateoas'
    implementation 'org.springframework.boot:spring-boot-starter-jersey'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.data:spring-data-rest-hal-browser'
    implementation 'org.springframework.session:spring-session-core'


    implementation 'org.springframework.boot:spring-boot-starter-security'

    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.2.1.RELEASE'
    compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.15'




    compileOnly 'org.projectlombok:lombok'

    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.boot:spring-boot-devtools")

    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    testImplementation 'io.projectreactor:reactor-test'

    implementation 'org.springframework.boot:spring-boot-starter-cache'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

}
test {
    useJUnitPlatform()
}

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

Ответы [ 2 ]

1 голос
/ 08 марта 2020

В MyUserDetailsService.java вы импортируете org.jvnet.hk2.annotations.Service, в то время как правильный org.springframework.stereotype.Service.

0 голосов
/ 07 марта 2020

Решение:

@SpringBootApplication
@ComponentScan 

должно быть в основном методе. Пока @EnableWebSecurity находится в классе SecurityConfigurer, Springboot знает, что кто-то пытается переопределить предоставленный Springboot класс безопасности. Проблема с моим основным методом состояла в том, что Springboot неправильно сканировал мои классы.

Я также узнал, что можно исключить предоставленный Springboot класс безопасности, поместив эту аннотацию над основным классом:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...