创建名为'inMemoryUserDetailsManager'

时间:2017-10-09 19:40:23

标签: java spring-boot spring-security

我正在尝试配置我的Spring安全身份验证类,以便对访问该应用程序的用户进行身份验证。在集成数据库之前,我使用纯文本文件作为占位符。问题是我在应用程序启动时遇到错误。

我的课程

@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private ServletContext servletContext;

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

    private static ArrayList<String> allowedUrlsForUsers = new ArrayList<String>();
    private static ArrayList<String> allowedUrlsForAdmins = new ArrayList<String>();

    static {
        BufferedReader reader = null;
        try {
            ClassLoader classLoader = Application.class.getClassLoader();
            File file = new File(classLoader.getResource("allowed-pages").getFile());

            reader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(file), ProjectConstants.getProjectEncoding()));

            String currentLine = null;
            while ((currentLine = reader.readLine()) != null) {
                if (!currentLine.isEmpty()) {
                    String[] allowedPage = currentLine.split(Pattern.quote(ProjectConstants.getDelimiter()));
                    if (allowedPage.length == 2) {
                        String[] roles = allowedPage[1].split(Pattern.quote(ProjectConstants.getSecondaryDelimiter()));

                        for (String role : roles) {
                            if (role.equals(ProjectConstants.getRoleUser()))
                                allowedUrlsForUsers.add(allowedPage[0]);
                            if (role.equals(ProjectConstants.getRoleAdmin()))
                                allowedUrlsForAdmins.add(allowedPage[0]);
                        }
                    }
                }
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }

    }

    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/css/**", "/js/**").permitAll().and().authorizeRequests()
                .antMatchers(allowedUrlsForAdmins.toArray(new String[0])).hasRole("ADMIN")
                .antMatchers(allowedUrlsForUsers.toArray(new String[0])).hasRole("USER").anyRequest().authenticated()
                .and().formLogin().loginPage("/login").defaultSuccessUrl(servletContext.getContextPath() + "/dashboard")
                .permitAll().and().logout().logoutUrl(servletContext.getContextPath() + "/logout")
                .logoutSuccessUrl(servletContext.getContextPath() + "/login?logout").clearAuthentication(true)
                .invalidateHttpSession(true).deleteCookies("JSESSIONID").permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(new CustomAuthenticationProvider());
    }

}

public class CustomAuthenticationProvider implements AuthenticationProvider {

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

    private static HashMap<String, User> credentialRepository = new HashMap<String, User>();

    static {
        BufferedReader reader = null;
        try {
            ClassLoader classLoader = Application.class.getClassLoader();
            File file = new File(classLoader.getResource("credentials").getFile());
            reader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(file), ProjectConstants.getProjectEncoding()));

            String currentLine = null;
            while ((currentLine = reader.readLine()) != null) {
                if (!currentLine.isEmpty()) {
                    String[] credential = currentLine.split(Pattern.quote(ProjectConstants.getDelimiter()));

                    if (credential.length == 3) {
                        String[] roles = credential[2].split(Pattern.quote(ProjectConstants.getSecondaryDelimiter()));
                        User user = new User(credential[0], credential[1], roles);
                        credentialRepository.put(user.username, user);
                    }
                }
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        User user = credentialRepository.get(authentication.getName().toLowerCase());
        if (user != null) {
            if (user.password.equals(authentication.getCredentials())) {
                List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
                for (String role : user.roles) {
                    auths.add(new SimpleGrantedAuthority(role));
                }

                return new UsernamePasswordAuthenticationToken(user.username, user.password, auths);
            } else {
                throw new BadCredentialsException("Invalid Password");
            }
        } else {
            throw new UsernameNotFoundException("Unknown Username");
        }
    }

    @Override
    public boolean supports(Class<?> arg0) {
        return true;
    }

    private static class User {
        String username;
        String password;
        ArrayList<String> roles;

        public User(String username, String password, String[] roles) {
            this.username = username;
            this.password = password;
            this.roles = new ArrayList<String>();
            for (String role : roles) {
                this.roles.add(role);
            }
        }
    }
}

当我运行应用程序时,会打印堆栈跟踪并启动失败。

[ERROR] 2017-10-09 22:11:14.494 SpringApplication - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'inMemoryUserDetailsManager' defined in class path resource [org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.provisioning.InMemoryUserDetailsManager]: Factory method 'inMemoryUserDetailsManager' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.provisioning.InMemoryUserDetailsManager.<init>([Lorg/springframework/security/core/userdetails/UserDetails;)V
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:605) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1249) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1098) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:122) ~[spring-boot-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386) [spring-boot-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1245) [spring-boot-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1233) [spring-boot-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at me.brkn.raspberrydashboard.Application.main(Application.java:15) [classes/:?]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.provisioning.InMemoryUserDetailsManager]: Factory method 'inMemoryUserDetailsManager' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.security.provisioning.InMemoryUserDetailsManager.<init>([Lorg/springframework/security/core/userdetails/UserDetails;)V
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:186) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:597) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    ... 18 more
Caused by: java.lang.NoSuchMethodError: org.springframework.security.provisioning.InMemoryUserDetailsManager.<init>([Lorg/springframework/security/core/userdetails/UserDetails;)V
    at org.springframework.boot.autoconfigure.security.AuthenticationManagerConfiguration.inMemoryUserDetailsManager(AuthenticationManagerConfiguration.java:61) ~[spring-boot-autoconfigure-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at org.springframework.boot.autoconfigure.security.AuthenticationManagerConfiguration$$EnhancerBySpringCGLIB$$9c5d1909.CGLIB$inMemoryUserDetailsManager$0(<generated>) ~[spring-boot-autoconfigure-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at org.springframework.boot.autoconfigure.security.AuthenticationManagerConfiguration$$EnhancerBySpringCGLIB$$9c5d1909$$FastClassBySpringCGLIB$$54415980.invoke(<generated>) ~[spring-boot-autoconfigure-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361) ~[spring-context-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.boot.autoconfigure.security.AuthenticationManagerConfiguration$$EnhancerBySpringCGLIB$$9c5d1909.inMemoryUserDetailsManager(<generated>) ~[spring-boot-autoconfigure-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_131]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:155) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:597) ~[spring-beans-5.0.0.RC4.jar:5.0.0.RC4]
    ... 18 more

我正在使用Spring Boot网络和安全启动器。我很乐意提出任何建议。

编辑1:我的依赖声明如下。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.BUILD-SNAPSHOT</version>
</parent>

<properties>
    <java.version>1.8</java.version>
    <tomcat.version>8.5.14</tomcat.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

提前致谢。

1 个答案:

答案 0 :(得分:0)

您必须包括此内容。

    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
    </dependency>