我继承了一个仅限GWT的webapp。 (好吧,不是真的"只有GWT"因为有一些REST控制器用于数据下载等...)
我想在普通的spring-mvc中开发新的视图,但我需要与GWT应用程序和新的非GWT视图保持并排。
我真的不是应用程序服务器/ servlet容器配置专家,我正在努力让这个工作。
现在我有一个主要问题:
当我在tomcat 8.0中运行war时,我的WebSecurityConfigurerAdapter中设置的规则不会被读取,因此我无需身份验证即可访问我的jsp。
当我在Eclipse (Neon Release(4.6.0))中使用GWT&#39> (GWT 2.7.0)运行配置的嵌入式时 Jetty,使用此安全配置。
通过以下方式访问GWT部分:/index.html
" web"部分是:/web/**
REST服务(实际上也没有保护):/download/**
,/file/**
build.gradle:
apply plugin: 'gwt'
apply plugin: 'jetty'
apply plugin: 'war'
apply plugin: 'project-report'
sourceCompatibility = 1.8
targetCompatibility = 1.8
compileJava.options.encoding = 'UTF-8'
configurations.all {
// check for updates every build
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
}
}
repositories {
mavenCentral()
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
dependencies {
compile project(':myapp_common')
compile project(':myapp_core')
compile 'org.apache.commons:commons-exec:1.3'
// PWT framework
compile 'fr.putnami.pwt:pwt:1.2.0-SNAPSHOT'
compile 'fr.putnami.pwt:pwt-google-analytics:1.2.0-SNAPSHOT'
compile 'fr.putnami.pwt:pwt-spring:1.2.0-SNAPSHOT'
compile 'org.aspectj:aspectjweaver:1.8.9'
compile 'org.springframework.security:spring-security-core:3.2.9.RELEASE'
compile 'org.springframework.security:spring-security-config:3.2.9.RELEASE'
compile 'org.springframework.security:spring-security-web:3.2.9.RELEASE'
compile 'commons-io:commons-io:2.4'
compile 'org.apache.commons:commons-compress:1.9'
compile 'org.apache.poi:poi:3.14'
compile 'org.apache.poi:poi-ooxml:3.14'
testCompile 'junit:junit:4.11'
testCompile 'org.mockito:mockito-all:1.10.8'
testCompile 'org.springframework:spring-test:4.1.1.RELEASE'
compile 'javax.servlet:jstl:1.2'
compile ('com.googlecode.gflot:gflot:3.3.0') {
exclude module: 'gwt-user'
}
// We do not want these in the .war
providedCompile 'com.google.gwt:gwt-dev:2.7.0'
providedCompile 'com.google.gwt:gwt-user:2.7.0'
}
gwt {
gwtVersion = '2.7.0'
minHeapSize = "512M";
maxHeapSize = "2G";
// Modules used in production
modules = ['com.mycompany.myapp.myapp']
// Modules used in dev mode and super dev mode.
devModules = ['com.mycompany.myapp.myappDev']
compiler {
strict = false;
}
superDev {
noPrecompile=true
}
}
task jettyDraftWar(type: JettyRunWar) {
dependsOn draftWar
webApp=draftWar.archivePath
}
[jettyDraftWar, jettyStop]*.stopPort = 8081
[jettyDraftWar, jettyStop]*.stopKey = 'stop'
war.dependsOn compileGwt
war {
baseName = "myapp_web"
if (project.hasProperty('environment')) {
FileTree tree = fileTree(dir: "src").include("**/*.$environment")
tree.each { File file ->
String origName = file.name.substring(0, file.name.length() - ".$environment".length())
File orig = new File(file.getParent(), origName)
war.rootSpec.exclude "**/" + origName
war.rootSpec.rename (file.name, origName)
}
version = environment
}
}
eclipse.classpath.file{
whenMerged{ classpath ->
def projectRefs = classpath.entries.findAll{entry -> entry.kind =='con' && entry.path.equals('com.google.gwt.eclipse.core.GWT_CONTAINER')}
//move the project references to the end of the list:
classpath.entries.removeAll(projectRefs)
classpath.entries.addAll(projectRefs)
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>delegatingChainFilter</filter-name>
<filter-class>fr.putnami.pwt.plugin.spring.web.filter.DelegatingChainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>delegatingChainFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
<!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or space-delimited
fully-qualified @Configuration classes. Fully-qualified packages may also
be specified for component-scanning -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.mycompany.myapp.server.config</param-value>
</context-param>
<!-- Spring configuration -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- Spring configuration -->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/mvc.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/web/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
MvcConfig.java:
@Configuration
@EnableTransactionManagement
@Import({ ComandServiceConfig.class, SecurityConfig.class })
@EnableWebMvc
@EnableScheduling
@ComponentScan(basePackages = { "com.mycompany.myapp.server.config", "com.mycompany.myapp.server.aop",
"com.mycompany.myapp.batch", "com.mycompany.myapp.server.mail", "com.mycompany.myapp.server.util",
"com.mycompany.myapp.server.service", "com.mycompany.myapp.server.repository", "com.mycompany.myapp.core.service" })
@PropertySource("classpath:application.properties")
@ImportResource("classpath:myapp_web-applicationContext.xml")
public class MvcConfig extends WebMvcConfigurerAdapter {
[...]
}
SecurityConfig.java:
package com.mycompany.myapp.server.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.context.AbstractSecurityWebApplicationInitializer;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
@Autowired
private UserDetailsService customUserDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests().antMatchers("/web/**", "/download/**", "/file/**").authenticated().anyRequest().permitAll().and().formLogin().loginPage("/index.html").permitAll();
httpSecurity.csrf().disable();
httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
}
@Bean(name = "authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
myapp_web-applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
">
<context:property-placeholder location="classpath:application.properties" ignore-unresolvable="true" local-override="false" />
<aop:config proxy-target-class="true" />
<bean name="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
<!-- Upload management -->
<bean name="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<bean class="com.mycompany.myapp.server.config.EncodingPostProcessor" />
<!-- Configures Spring Data JPA and sets the base package of my DAOs. -->
<jpa:repositories base-package="com.mycompany.myapp.server.repository" />
</beans>