2

我正在关注此视频中的教程:https ://www.youtube.com/watch?v=X80nJ5T7YpE&list=PLqq-6Pq4lTTYTEooakHchTGglSvkZAjnE&index=12

我的代码处于 7:30 标记的状态。无论出于何种原因,我似乎无法让SecurityConfigurer.java该类识别我的自定义 UserDetailsS​​ervice 类,称为MyUserDetailsService.java.

预期的行为是,当我转到我在HelloResource.Java课堂上指定的 /hello 端点时,应该会生成一个登录页面。我应该能够使用该loadUserByUsername方法的硬编码返回用户值以及用户名和密码“foo”登录到网页。

不管我做了什么改变,似乎总是loadUserByUsername没有调用该方法(我已经用断点/打印语句证明了这一点)。这让我相信可能存在一些组件扫描问题,但我还没有看到任何工作!

我已经在这些链接上尝试过解决方案: OneTwoThree以及更多。这是我的相关文件:

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";
    }

}

MyUserDetailsS​​ervice.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<>());
    }
}

安全配置器.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();
    }
}

应用程序属性

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

构建.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()
}

除此之外,我无法对正在发生的事情做出正面或反面。让我知道,谢谢。

4

2 回答 2

1

MyUserDetailsService.java您正在导入org.jvnet.hk2.annotations.Service时,正确的是org.springframework.stereotype.Service.

于 2020-03-07T21:02:58.410 回答
0

解决方案:

@SpringBootApplication
@ComponentScan 

应该在 main 方法中。只要 @EnableWebSecurity 在 SecurityConfigurer 类中,Springboot 就知道有人试图覆盖 Springboot 提供的 Security 类。我的主要方法的问题是 Springboot 没有正确扫描我的类。

我还了解到,可以通过将此注释放在主类之上来排除 Springboot 提供的 Security 类:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
于 2020-03-07T20:05:21.123 回答