First attempt at moving to Spring Boot 2

This commit is contained in:
Nanne Baars 2019-09-12 17:22:03 +02:00
parent a56f41e0ea
commit 361249c666
33 changed files with 271 additions and 398 deletions

View File

@ -21,7 +21,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<version>2.1.8.RELEASE</version>
</parent>
<licenses>

View File

@ -121,8 +121,7 @@
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>2.1.2.RELEASE</version>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>

View File

@ -39,12 +39,15 @@ import org.owasp.webgoat.asciidoc.WebGoatVersionMacro;
import org.owasp.webgoat.asciidoc.WebWolfMacro;
import org.owasp.webgoat.asciidoc.WebWolfRootMacro;
import org.owasp.webgoat.i18n.Language;
import org.thymeleaf.TemplateProcessingParameters;
import org.thymeleaf.resourceresolver.IResourceResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.templateresolver.FileTemplateResolver;
import org.thymeleaf.templateresource.ITemplateResource;
import org.thymeleaf.templateresource.StringTemplateResource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.Map;
import static org.asciidoctor.Asciidoctor.Factory.create;
@ -57,7 +60,7 @@ import static org.asciidoctor.Asciidoctor.Factory.create;
* </code>
*/
@Slf4j
public class AsciiDoctorTemplateResolver extends TemplateResolver {
public class AsciiDoctorTemplateResolver extends FileTemplateResolver {
private static final Asciidoctor asciidoctor = create();
private static final String PREFIX = "doc:";
@ -65,72 +68,56 @@ public class AsciiDoctorTemplateResolver extends TemplateResolver {
public AsciiDoctorTemplateResolver(Language language) {
this.language = language;
setResourceResolver(new AdocResourceResolver());
setResolvablePatterns(Sets.newHashSet(PREFIX + "*"));
}
@Override
protected String computeResourceName(TemplateProcessingParameters params) {
String templateName = params.getTemplateName();
return templateName.substring(PREFIX.length());
}
private class AdocResourceResolver implements IResourceResolver {
@Override
public InputStream getResourceAsStream(TemplateProcessingParameters params, String resourceName) {
try (InputStream is = readInputStreamOrFallbackToEnglish(resourceName, language)) {
if (is == null) {
log.warn("Resource name: {} not found, did you add the adoc file?", resourceName);
return new ByteArrayInputStream(new byte[0]);
} else {
StringWriter writer = new StringWriter();
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
extensionRegistry.inlineMacro("webWolfRootLink", WebWolfRootMacro.class);
extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class);
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8));
}
} catch (IOException e) {
//no html yet
return new ByteArrayInputStream(new byte[0]);
}
}
/**
* The resource name is for example HttpBasics_content1.adoc. This is always located in the following directory:
* <code>plugin/HttpBasics/lessonPlans/en/HttpBasics_content1.adoc</code>
*/
private String computeResourceName(String resourceName, String language) {
return String.format("lessonPlans/%s/%s", language, resourceName);
}
private InputStream readInputStreamOrFallbackToEnglish(String resourceName, Language language) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, language.getLocale().getLanguage()));
protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
var templateName = resourceName.substring(PREFIX.length());
try (InputStream is = readInputStreamOrFallbackToEnglish(templateName, language)) {
if (is == null) {
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, "en"));
log.warn("Resource name: {} not found, did you add the adoc file?", templateName);
return new StringTemplateResource("");
} else {
StringWriter writer = new StringWriter();
JavaExtensionRegistry extensionRegistry = asciidoctor.javaExtensionRegistry();
extensionRegistry.inlineMacro("webWolfLink", WebWolfMacro.class);
extensionRegistry.inlineMacro("webWolfRootLink", WebWolfRootMacro.class);
extensionRegistry.inlineMacro("webGoatVersion", WebGoatVersionMacro.class);
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
return new StringTemplateResource(writer.getBuffer().toString());
}
return is;
}
private Map<String, Object> createAttributes() {
Map<String, Object> attributes = Maps.newHashMap();
attributes.put("source-highlighter", "coderay");
attributes.put("backend", "xhtml");
Map<String, Object> options = Maps.newHashMap();
options.put("attributes", attributes);
return options;
}
@Override
public String getName() {
return "adocResourceResolver";
} catch (IOException e) {
//no html yet
return new StringTemplateResource("");
}
}
/**
* The resource name is for example HttpBasics_content1.adoc. This is always located in the following directory:
* <code>plugin/HttpBasics/lessonPlans/en/HttpBasics_content1.adoc</code>
*/
private String computeResourceName(String resourceName, String language) {
return String.format("lessonPlans/%s/%s", language, resourceName);
}
private InputStream readInputStreamOrFallbackToEnglish(String resourceName, Language language) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, language.getLocale().getLanguage()));
if (is == null) {
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, "en"));
}
return is;
}
private Map<String, Object> createAttributes() {
Map<String, Object> attributes = Maps.newHashMap();
attributes.put("source-highlighter", "coderay");
attributes.put("backend", "xhtml");
Map<String, Object> options = Maps.newHashMap();
options.put("attributes", attributes);
return options;
}
}

View File

@ -1,47 +1,46 @@
/**
*************************************************************************************************
*
*
* ************************************************************************************************
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* <p>
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author WebGoat
* @since October 28, 2003
* @version $Id: $Id
* @since October 28, 2003
*/
package org.owasp.webgoat;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;
import lombok.SneakyThrows;
import org.springframework.core.io.ResourceLoader;
import org.thymeleaf.TemplateProcessingParameters;
import org.thymeleaf.resourceresolver.IResourceResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.templateresolver.FileTemplateResolver;
import org.thymeleaf.templateresource.ITemplateResource;
import org.thymeleaf.templateresource.StringTemplateResource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
@ -53,42 +52,29 @@ import java.util.Map;
*
* Thymeleaf will invoke this resolver based on the prefix and this implementation will resolve the html in the plugins directory
*/
public class LessonTemplateResolver extends TemplateResolver {
public class LessonTemplateResolver extends FileTemplateResolver {
private final static String PREFIX = "lesson:";
private final File pluginTargetDirectory;
private ResourceLoader resourceLoader;
private Map<String, byte[]> resources = Maps.newHashMap();
public LessonTemplateResolver(File pluginTargetDirectory, ResourceLoader resourceLoader) {
this.pluginTargetDirectory = pluginTargetDirectory;
public LessonTemplateResolver(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
setResourceResolver(new LessonResourceResolver());
setResolvablePatterns(Sets.newHashSet(PREFIX + "*"));
}
@Override
protected String computeResourceName(TemplateProcessingParameters params) {
String templateName = params.getTemplateName();
return templateName.substring(PREFIX.length());
}
private class LessonResourceResolver implements IResourceResolver {
@Override
@SneakyThrows
public InputStream getResourceAsStream(TemplateProcessingParameters params, String resourceName) {
byte[] resource = resources.get(resourceName);
if (resource == null) {
resource = ByteStreams.toByteArray(resourceLoader.getResource("classpath:/html/" + resourceName + ".html").getInputStream());
resources.put(resourceName, resource);
protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate, String template, String resourceName, String characterEncoding, Map<String, Object> templateResolutionAttributes) {
var templateName = resourceName.substring(PREFIX.length());;
byte[] resource = resources.get(templateName);
if (resource == null) {
try {
resource = ByteStreams.toByteArray(resourceLoader.getResource("classpath:/html/" + templateName + ".html").getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
return new ByteArrayInputStream(resource);
}
@Override
public String getName() {
return "lessonResourceResolver";
resources.put(resourceName, resource);
}
return new StringTemplateResource(new String(resource, StandardCharsets.UTF_8));
}
}
}

View File

@ -30,41 +30,38 @@
*/
package org.owasp.webgoat;
import com.google.common.collect.Sets;
import org.owasp.webgoat.i18n.Language;
import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.LabelDebugger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;
import java.io.File;
import java.util.Set;
/**
* Configuration for Spring MVC
*/
@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
public class MvcConfiguration implements WebMvcConfigurer {
private static final String UTF8 = "UTF-8";
@Autowired
@Qualifier("pluginTargetDirectory")
private File pluginTargetDirectory;
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
@ -74,13 +71,21 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
//registry.addViewController("/list_users").setViewName("list_users");
}
@Bean
public ViewResolver viewResolver(SpringTemplateEngine thymeleafTemplateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(thymeleafTemplateEngine);
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
@Bean
public TemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) {
public ITemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("classpath:/templates/");
resolver.setSuffix(".html");
resolver.setOrder(1);
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setOrder(2);
resolver.setCacheable(false);
resolver.setCharacterEncoding(UTF8);
resolver.setApplicationContext(applicationContext);
@ -89,8 +94,8 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Bean
public LessonTemplateResolver lessonTemplateResolver(ResourceLoader resourceLoader) {
LessonTemplateResolver resolver = new LessonTemplateResolver(pluginTargetDirectory, resourceLoader);
resolver.setOrder(2);
LessonTemplateResolver resolver = new LessonTemplateResolver(resourceLoader);
resolver.setOrder(0);
resolver.setCacheable(false);
resolver.setCharacterEncoding(UTF8);
return resolver;
@ -100,19 +105,20 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(Language language) {
AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(language);
resolver.setCacheable(false);
resolver.setOrder(3);
resolver.setOrder(1);
resolver.setCharacterEncoding(UTF8);
return resolver;
}
@Bean
public SpringTemplateEngine thymeleafTemplateEngine(TemplateResolver springThymeleafTemplateResolver,
public SpringTemplateEngine thymeleafTemplateEngine(ITemplateResolver springThymeleafTemplateResolver,
LessonTemplateResolver lessonTemplateResolver,
AsciiDoctorTemplateResolver asciiDoctorTemplateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setEnableSpringELCompiler(true);
engine.addDialect(new SpringSecurityDialect());
engine.setTemplateResolvers(
Sets.newHashSet(springThymeleafTemplateResolver, lessonTemplateResolver, asciiDoctorTemplateResolver));
Set.of(lessonTemplateResolver, asciiDoctorTemplateResolver, springThymeleafTemplateResolver));
return engine;
}
@ -123,12 +129,10 @@ public class MvcConfiguration extends WebMvcConfigurerAdapter {
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/plugin_lessons/**").addResourceLocations("file:///" + pluginTargetDirectory.toString() + "/");
registry.addResourceHandler("/images/**").addResourceLocations("classpath:/images/");
registry.addResourceHandler("/lesson_js/**").addResourceLocations("classpath:/js/");
registry.addResourceHandler("/lesson_css/**").addResourceLocations("classpath:/css/");
registry.addResourceHandler("/video/**").addResourceLocations("classpath:/video/");
super.addResourceHandlers(registry);
}
@Bean

View File

@ -30,15 +30,11 @@
*/
package org.owasp.webgoat;
import org.owasp.webgoat.plugins.PluginEndpointPublisher;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
@ -66,16 +62,6 @@ public class WebGoat {
return new UserSessionData("test", "data");
}
@Bean
public PluginEndpointPublisher pluginEndpointPublisher(ApplicationContext applicationContext) {
return new PluginEndpointPublisher(applicationContext);
}
@Bean
public Course course(PluginEndpointPublisher pluginEndpointPublisher) {
return new PluginsLoader(pluginEndpointPublisher).loadPlugins();
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();

View File

@ -35,6 +35,7 @@ import org.owasp.webgoat.users.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
@ -42,6 +43,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
/**
* Security configuration for WebGoat.
@ -90,4 +92,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public UserDetailsService userDetailsServiceBean() throws Exception {
return userDetailsService;
}
@Override
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@SuppressWarnings("deprecation")
@Bean
public NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
}

View File

@ -41,7 +41,8 @@ import org.springframework.beans.factory.annotation.Autowired;
* </p>
* Note: each subclass should declare this annotation otherwise the WebGoat framework cannot find your endpoint.
*/
public abstract class AssignmentEndpoint extends Endpoint {
//TODO: rename to assignment
public abstract class AssignmentEndpoint {
@Autowired
private UserTrackerRepository userTrackerRepository;
@ -76,11 +77,6 @@ public abstract class AssignmentEndpoint extends Endpoint {
return userSessionData;
}
@Override
public final String getPath() {
return this.getClass().getAnnotationsByType(AssignmentPath.class)[0].value();
}
/**
* Convenience method for create a successful result:
*

View File

@ -1,5 +1,9 @@
package org.owasp.webgoat.assignments;
import org.springframework.core.annotation.AliasFor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -10,7 +14,15 @@ import java.lang.annotation.Target;
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
//@RequestMapping
public @interface AssignmentPath {
String value();
// @AliasFor(annotation = RequestMapping.class)
String[] path() default {};
// @AliasFor(annotation = RequestMapping.class)
RequestMethod[] method() default {};
// @AliasFor("path")
String value() default "";
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 Bruce Mayhew
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*/
package org.owasp.webgoat.assignments;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
public abstract class Endpoint implements MvcEndpoint {
@Override
public final boolean isSensitive() {
return false;
}
@Override
public final Class<? extends org.springframework.boot.actuate.endpoint.Endpoint> getEndpointType() {
return null;
}
}

View File

@ -52,8 +52,8 @@ public class Assignment {
//Hibernate
}
public Assignment(String name, String path) {
this(name, path, Lists.newArrayList());
public Assignment(String name) {
this(name, name, Lists.newArrayList());
}
public Assignment(String name, String path, List<String> hints) {

View File

@ -1,66 +0,0 @@
package org.owasp.webgoat.plugins;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.Endpoint;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import java.util.List;
/**
* ************************************************************************************************
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author nbaars
* @version $Id: $Id
* @since October 16, 2016
*/
@Slf4j
public class PluginEndpointPublisher {
private AbstractApplicationContext applicationContext;
public PluginEndpointPublisher(ApplicationContext applicationContext) {
this.applicationContext = (AbstractApplicationContext) applicationContext;
}
public void publish(List<Class<Endpoint>> endpoints) {
endpoints.forEach(e -> publishEndpoint(e));
}
private void publishEndpoint(Class<? extends MvcEndpoint> e) {
try {
BeanDefinition beanDefinition = new RootBeanDefinition(e, Autowire.BY_TYPE.value(), true);
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
beanFactory.registerBeanDefinition(beanDefinition.getBeanClassName(), beanDefinition);
} catch (Exception ex) {
log.error("Failed to register " + e.getSimpleName() + " as endpoint with Spring, skipping...");
}
}
}

View File

@ -3,19 +3,12 @@ package org.owasp.webgoat.plugins;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.lessons.NewLesson;
import java.net.URL;
import java.util.List;
import java.util.stream.Collectors;
/**
* Plugin resource
*
* @author nbaars
* @since 3/4/17.
*/
@AllArgsConstructor
@Getter
public class PluginResource {
@ -27,13 +20,6 @@ public class PluginResource {
return classes.stream().filter(c -> c.getSuperclass() == NewLesson.class).collect(Collectors.toList());
}
public List<Class<Endpoint>> getEndpoints() {
return classes.stream().
filter(c -> c.getSuperclass() == AssignmentEndpoint.class || c.getSuperclass() == Endpoint.class).
map(c -> (Class<Endpoint>) c).
collect(Collectors.toList());
}
public List<Class<AssignmentEndpoint>> getAssignments(Class lesson) {
return classes.stream().
filter(c -> c.getSuperclass() == AssignmentEndpoint.class).

View File

@ -8,14 +8,22 @@ import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.NewLesson;
import org.owasp.webgoat.session.Course;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.List;
import java.util.Map;
@ -56,13 +64,12 @@ import static java.util.stream.Collectors.toList;
*/
@AllArgsConstructor
@Slf4j
@Configuration
public class PluginsLoader {
private final PluginEndpointPublisher pluginEndpointPublisher;
/**
* <p>createLessonsFromPlugins.</p>
*/
@Bean
public Course loadPlugins() {
List<AbstractLesson> lessons = Lists.newArrayList();
for (PluginResource plugin : findPluginResources()) {
@ -70,7 +77,7 @@ public class PluginsLoader {
plugin.getLessons().forEach(c -> {
NewLesson lesson = null;
try {
lesson = (NewLesson) c.newInstance();
lesson = (NewLesson) c.getConstructor().newInstance();
log.trace("Lesson loaded: {}", lesson.getId());
} catch (Exception e) {
log.error("Error while loading:" + c, e);
@ -78,7 +85,6 @@ public class PluginsLoader {
List<Class<AssignmentEndpoint>> assignments = plugin.getAssignments(c);
lesson.setAssignments(createAssignment(assignments));
lessons.add(lesson);
pluginEndpointPublisher.publish(plugin.getEndpoints());
});
} catch (Exception e) {
log.error("Error in loadLessons: ", e);
@ -97,7 +103,29 @@ public class PluginsLoader {
}
private String getPath(Class<AssignmentEndpoint> e) {
return e.getAnnotationsByType(AssignmentPath.class)[0].value();
for (Method m : e.getMethods()) {
if (m.getReturnType() == AttackResult.class) {
var mapping = m.getAnnotation(RequestMapping.class);
if (mapping == null) {
log.error("AttackResult method found without mapping in: {}", e.getSimpleName());
} else {
return getMapping(m);
}
}
}
return "";
}
private String getMapping(Method m) {
String[] path = null;
if (m.getAnnotation(RequestMapping.class) != null) {
path = m.getAnnotation(RequestMapping.class).path();
} else if (m.getAnnotation(PostMapping.class) != null) {
path = m.getAnnotation(PostMapping.class).path();
} else if (m.getAnnotation(GetMapping.class) != null) {
path = m.getAnnotation(GetMapping.class).value();
}
return path != null && path.length > 0 ? path[0] : "";
}
private List<String> getHints(Class<AssignmentEndpoint> e) {
@ -107,8 +135,6 @@ public class PluginsLoader {
return Lists.newArrayList();
}
@SneakyThrows
public List<PluginResource> findPluginResources() {
final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);

View File

@ -76,7 +76,7 @@ public class LessonProgressService {
}
private List<LessonOverview> toJson(Map<Assignment, Boolean> map) {
ArrayList<LessonOverview> result = Lists.newArrayList();
List<LessonOverview> result = new ArrayList();
for (Map.Entry<Assignment, Boolean> entry : map.entrySet()) {
result.add(new LessonOverview(entry.getKey(), entry.getValue()));
}

View File

@ -1,7 +1,7 @@
server.error.include-stacktrace=always
server.error.path=/error.html
server.session.timeout=600
server.contextPath=/WebGoat
server.servlet.context-path=/WebGoat
server.port=${WEBGOAT_PORT:8080}
server.address=${WEBGOAT_HOST:127.0.0.1}
@ -17,6 +17,11 @@ spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
logging.level.org.thymeleaf=DEBUG
logging.level.org.thymeleaf.TemplateEngine.CONFIG=TRACE
logging.level.org.thymeleaf.TemplateEngine.TIMER=TRACE
logging.level.org.thymeleaf.TemplateEngine.cache.TEMPLATE_CACHE=TRACE
logging.level.org.springframework.web=TRACE
logging.level.org.springframework=INFO
logging.level.org.springframework.boot.devtools=INFO
logging.level.org.owasp=DEBUG
@ -25,7 +30,6 @@ logging.level.org.owasp.webgoat=TRACE
# Needed for creating a vulnerable web application
security.enable-csrf=false
spring.resources.cache-period=0
spring.thymeleaf.cache=false
webgoat.start.hsqldb=true

View File

@ -28,15 +28,15 @@
<!-- JS -->
<script src="js/modernizr-2.6.2.min.js"/>
<script src="js/modernizr-2.6.2.min.js"></script>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"/>
<script src="js/respond.min.js"/>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
<!-- Require.js used to load js asynchronously -->
<script src="js/libs/require.min.js" data-main="js/main.js"/>
<script src="js/libs/require.min.js" data-main="js/main.js"></script>
<meta http-equiv="Content-Type" content="text/id; charset=ISO-8859-1"/>
<title>WebGoat</title>
</head>
@ -67,8 +67,7 @@
<li role="presentation"><a role="menuitem" tabindex="-1" th:href="@{/logout}"
th:text="#{logout}">Logout</a></li>
<li role="presentation" class="divider"></li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">User: <span
th:text="${#authentication.name}"></span></a>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">User: <span sec:authentication="name"></span></a>
</li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">Role:
<span sec:authorize="hasAuthority('WEBGOAT_USER')">User</span>
@ -134,14 +133,14 @@
<div id="lesson-content-wrapper" class="panel">
<div class="" id="error-notification-container">
<div class="" id="error-notification">
<i class="fa fa-exclamation-circle"/> There was an unexpected error. Please try
again.
<i class="fa fa-exclamation-circle"> There was an unexpected error. Please try
again.</i>
</div>
</div>
<div class="" id="help-controls">
<button class="btn btn-primary btn-xs btn-danger help-button"
id="show-source-button">
<i class="fa fa-code"/>
<i class="fa fa-code"></i>
</button>
<button class="btn btn-primary btn-xs btn-danger help-button"
id="show-hints-button" th:text="#{show.hints}">Show hints

View File

@ -6,9 +6,9 @@ import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

View File

@ -17,6 +17,8 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
@ -71,7 +73,7 @@ public class LessonProgressServiceTest {
@Before
public void setup() {
Assignment assignment = new Assignment("test", "test");
Assignment assignment = new Assignment("test", "test", List.of());
when(userTrackerRepository.findByUser(anyString())).thenReturn(userTracker);
when(userTracker.getLessonTracker(any(AbstractLesson.class))).thenReturn(lessonTracker);
when(websession.getCurrentLesson()).thenReturn(lesson);

View File

@ -48,7 +48,7 @@ public class LessonTrackerTest {
@Test
public void allAssignmentsSolvedShouldMarkLessonAsComplete() {
AbstractLesson lesson = mock(AbstractLesson.class);
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment", "")));
when(lesson.getAssignments()).thenReturn(Lists.newArrayList(new Assignment("assignment", "assignment", List.of(""))));
LessonTracker lessonTracker = new LessonTracker(lesson);
lessonTracker.assignmentSolved("assignment");
@ -58,8 +58,8 @@ public class LessonTrackerTest {
@Test
public void noAssignmentsSolvedShouldMarkLessonAsInComplete() {
AbstractLesson lesson = mock(AbstractLesson.class);
Assignment a1 = new Assignment("a1", "a1");
Assignment a2 = new Assignment("a2", "a2");
Assignment a1 = new Assignment("a1");
Assignment a2 = new Assignment("a2");
List<Assignment> assignments = Lists.newArrayList(a1, a2);
when(lesson.getAssignments()).thenReturn(assignments);
LessonTracker lessonTracker = new LessonTracker(lesson);
@ -73,7 +73,7 @@ public class LessonTrackerTest {
@Test
public void solvingSameAssignmentShouldNotAddItTwice() {
AbstractLesson lesson = mock(AbstractLesson.class);
Assignment a1 = new Assignment("a1", "a1");
Assignment a1 = new Assignment("a1");
List<Assignment> assignments = Lists.newArrayList(a1);
when(lesson.getAssignments()).thenReturn(assignments);
LessonTracker lessonTracker = new LessonTracker(lesson);

View File

@ -5,7 +5,6 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.UserTracker;
@ -27,7 +26,7 @@ import java.util.stream.IntStream;
* @since 3/23/17.
*/
@Slf4j
public class Flag extends Endpoint {
public class Flag { //extends Endpoint {
public static final Map<Integer, String> FLAGS = Maps.newHashMap();
@Autowired
@ -48,10 +47,10 @@ public class Flag extends Endpoint {
IntStream.range(1, 10).forEach(i -> FLAGS.put(i, UUID.randomUUID().toString()));
}
@Override
public String getPath() {
return "challenge/flag";
}
// @Override
// public String getPath() {
// return "challenge/flag";
// }
@RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody

View File

@ -63,6 +63,5 @@ public class Assignment1 extends AssignmentEndpoint {
public static boolean containsHeader(HttpServletRequest request) {
return StringUtils.hasText(request.getHeader("X-Forwarded-For"));
}
}

View File

@ -7,7 +7,6 @@ package org.owasp.webgoat.plugin;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;
import org.owasp.webgoat.assignments.Endpoint;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
@ -30,7 +29,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Map;
public class Salaries extends Endpoint {
public class Salaries { // {extends Endpoint {
@Value("${webgoat.user.directory}")
private String webGoatHomeDirectory;
@ -84,10 +83,10 @@ public class Salaries extends Endpoint {
return json;
}
@Override
public String getPath() {
return "/clientSideFiltering/salaries";
}
// @Override
// public String getPath() {
// return "/clientSideFiltering/salaries";
// }
}

View File

@ -1,6 +1,5 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.beans.factory.annotation.Autowired;
@ -20,7 +19,7 @@ import java.util.Random;
* Created by jason on 9/30/17.
*/
public class CSRFGetFlag extends Endpoint {
public class CSRFGetFlag {
@Autowired
UserSessionData userSessionData;
@ -71,9 +70,9 @@ public class CSRFGetFlag extends Endpoint {
return response;
}
@Override
public String getPath() {
return "/csrf/basic-get-flag";
}
//
// @Override
// public String getPath() {
// return "/csrf/basic-get-flag";
// }
}

View File

@ -4,10 +4,7 @@ import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@ -44,15 +41,14 @@ import java.io.IOException;
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
@AssignmentPath("/HttpBasics/attack1")
@RestController
@AssignmentHints({"http-basics.hints.http_basics_lesson.1"})
public class HttpBasicsLesson extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public
@PostMapping("/HttpBasics/attack1")
@ResponseBody
AttackResult completed(@RequestParam String person) throws IOException {
if (!person.toString().equals("")) {
public AttackResult completed(@RequestParam String person) {
if (!person.equals("")) {
return trackProgress(success()
.feedback("http-basics.reversed")
.feedbackArgs(new StringBuffer(person).reverse().toString())

View File

@ -4,10 +4,7 @@ import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@ -15,49 +12,51 @@ import java.io.IOException;
/**
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* <p>
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
* <p>
* For details, please see http://webgoat.github.io
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
@AssignmentPath("/HttpBasics/attack2")
@RestController
@AssignmentHints({"http-basics.hints.http_basic_quiz.1", "http-basics.hints.http_basic_quiz.2"})
@AssignmentPath("HttpBasics/attack2")
public class HttpBasicsQuiz extends AssignmentEndpoint {
@RequestMapping(method = RequestMethod.POST)
public @ResponseBody AttackResult completed(@RequestParam String answer, @RequestParam String magic_answer, @RequestParam String magic_num, HttpServletRequest request) throws IOException {
@PostMapping("/HttpBasics/attack2")
@ResponseBody
public AttackResult completed(@RequestParam String answer, @RequestParam String magic_answer, @RequestParam String magic_num, HttpServletRequest request) throws IOException {
if ("POST".equals(answer.toUpperCase()) && magic_answer.equals(magic_num)) {
return trackProgress(success().build());
} else {
if (!"POST".equals(answer.toUpperCase())) {
return trackProgress(success().build());
} else {
if (!"POST".equals(answer.toUpperCase())) {
return trackProgress(failed().feedback("http-basics.incorrect").build());
}
if (!magic_answer.equals(magic_num)){
}
if (!magic_answer.equals(magic_num)) {
return trackProgress(failed().feedback("http-basics.magic").build());
}
}
return trackProgress(failed().build());
}
}
}
return trackProgress(failed().build());
}
}

View File

@ -1,7 +1,6 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
@ -12,7 +11,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@ -46,7 +44,7 @@ import java.util.Map;
* @since January 3, 2017
*/
public class IDORViewOwnProfile extends Endpoint{
public class IDORViewOwnProfile {
@Autowired
UserSessionData userSessionData;
@ -74,8 +72,8 @@ public class IDORViewOwnProfile extends Endpoint{
return details;
}
@Override
public String getPath() {
return "/IDOR/profile";
}
// @Override
// public String getPath() {
// return "/IDOR/profile";
// }
}

View File

@ -1,6 +1,5 @@
package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
@ -13,7 +12,7 @@ import javax.servlet.http.HttpServletRequest;
import java.sql.*;
import java.util.HashMap;
public class Users extends Endpoint{
public class Users {
@Autowired
private WebSession webSession;
@ -102,8 +101,8 @@ public class Users extends Endpoint{
return webSession;
}
@Override
public String getPath() {
return "/access-control/list-users";
}
// @Override
// public String getPath() {
// return "/access-control/list-users";
// }
}

View File

@ -1,7 +1,6 @@
package org.owasp.webgoat.plugin;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -41,17 +40,17 @@ import java.io.PrintWriter;
* @since November 17, 2016
*/
@Slf4j
public class Ping extends Endpoint {
public class Ping {
@Value("${webgoat.user.directory}")
private String webGoatHomeDirectory;
@Autowired
private WebSession webSession;
@Override
public String getPath() {
return "XXE/ping";
}
// @Override
// public String getPath() {
// return "XXE/ping";
// }
@RequestMapping(method = RequestMethod.GET)
@ResponseBody

View File

@ -147,12 +147,11 @@
<!--</dependency>-->
<!-- /lessons -->
<!-- devtools no longer working with Java 11 and Spring Boot version 1.* enable again once we move to 2.0-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-devtools</artifactId>-->
<!--<optional>true</optional>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
@ -171,7 +170,7 @@
<requiresUnpack>
<dependency>
<groupId>org.thymeleaf.extra</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<artifactId>thymeleaf-extras-springsecurity5++</artifactId>
</dependency>
<dependency>
<groupId>org.asciidoctor</groupId>

View File

@ -4,7 +4,7 @@ import lombok.extern.slf4j.Slf4j;
import org.hsqldb.server.Server;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

View File

@ -27,11 +27,7 @@ package org.owasp.webgoat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Import;
import java.util.Map;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* Main entry point, this project is here to get all the lesson jars included to the final jar file
@ -39,7 +35,7 @@ import java.util.Map;
* @author nbaars
* @date 2/21/17
*/
@SpringBootApplication
@SpringBootApplication(scanBasePackages = "org.owasp.webgoat")
@Slf4j
public class StartWebGoat extends SpringBootServletInitializer {

View File

@ -46,20 +46,17 @@
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>2.1.2.RELEASE</version>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- devtools no longer working with Java 11 and Spring Boot version 1.* enable again once we move to 2.0-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-devtools</artifactId>-->
<!--<optional>true</optional>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.webjars</groupId>