diff --git a/build.gradle b/build.gradle index 55228eeec4..589ad50bc7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,4 @@ +import sun.awt.geom.AreaOp.IntOp; import groovy.text.SimpleTemplateEngine buildscript { @@ -6,6 +7,7 @@ buildscript { } dependencies { classpath("org.springframework.build.gradle:propdeps-plugin:0.0.3") + classpath("org.springframework.build.gradle:docbook-reference-plugin:0.2.7") classpath("org.springframework.build.gradle:bundlor-plugin:0.1.2") } } @@ -22,7 +24,8 @@ allprojects { group = 'org.springframework.security' repositories { - maven { url "http://repo.springsource.org/plugins-release" } + maven { url "http://repo.springsource.org/libs-release" } + maven { url "http://repo.springsource.org/plugins-release" } } } @@ -57,7 +60,7 @@ configure(subprojects - coreModuleProjects) { configure(javaProjects) { apply from: "$rootDir/gradle/javaprojects.gradle" apply from: "$rootDir/gradle/release-checks.gradle" - apply from: "$rootDir/gradle/maven-deployment.gradle" + apply from: "$rootDir/gradle/maven-deployment.gradle" } configure(coreModuleProjects) { @@ -94,7 +97,7 @@ task coreBuild { // Task for creating the distro zip task dist(type: Zip) { - dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' || task.name.endsWith('Zip') } + dependsOn subprojects*.tasks*.matching { task -> task.name == 'assemble' || task.name.endsWith('Zip') || task.name.endsWith('generatePom') } classifier = 'dist' evaluationDependsOn(':docs') @@ -110,8 +113,14 @@ task dist(type: Zip) { } into('dist') { from coreModuleProjects.collect {project -> project.libsDir } - from project(':spring-security-samples-tutorial').libsDir - from project(':spring-security-samples-contacts').libsDir + } + sampleProjects.each { project-> + into("$zipRootDir/samples/$project.name") { + from(project.projectDir) { + include "src/main/**" + include "pom.xml" + } + } } } } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 7de8ea91a9..04570ae8ae 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -12,28 +12,6 @@ repositories { } } -// Docbook Plugin -dependencies { - def fopDeps = [ 'org.apache.xmlgraphics:fop:0.95-1@jar', - 'org.apache.xmlgraphics:xmlgraphics-commons:1.3', - 'org.apache.xmlgraphics:batik-bridge:1.7@jar', - 'org.apache.xmlgraphics:batik-util:1.7@jar', - 'org.apache.xmlgraphics:batik-css:1.7@jar', - 'org.apache.xmlgraphics:batik-dom:1.7', - 'org.apache.xmlgraphics:batik-svg-dom:1.7@jar', - 'org.apache.avalon.framework:avalon-framework-api:4.3.1'] - groovy localGroovy() - compile gradleApi(), - 'xml-resolver:xml-resolver:1.2', - 'xerces:xercesImpl:2.9.1', - 'saxon:saxon:6.5.3', - 'net.java.dev.jets3t:jets3t:0.6.1', - fopDeps - - runtime 'net.sf.xslthl:xslthl:2.0.1', - 'net.sf.docbook:docbook-xsl:1.75.2:ns-resources@zip' -} - // GAE dependencies { compile 'com.google.appengine:appengine-tools-sdk:1.4.2' diff --git a/buildSrc/src/main/groovy/docbook/DocbookPlugin.groovy b/buildSrc/src/main/groovy/docbook/DocbookPlugin.groovy deleted file mode 100644 index d9c699c061..0000000000 --- a/buildSrc/src/main/groovy/docbook/DocbookPlugin.groovy +++ /dev/null @@ -1,301 +0,0 @@ -package docbook; - -import org.gradle.api.Plugin; -import org.gradle.api.GradleException; -import org.gradle.api.DefaultTask; -import org.gradle.api.Task; -import org.gradle.api.Project; -import org.gradle.api.Action; -import org.gradle.api.tasks.*; -import org.gradle.api.file.FileCollection; - -import org.xml.sax.XMLReader; -import org.xml.sax.InputSource; -import org.apache.xml.resolver.CatalogManager; -import org.apache.xml.resolver.tools.CatalogResolver; - -import javax.xml.parsers.SAXParserFactory; -import javax.xml.transform.*; -import javax.xml.transform.sax.SAXSource; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; -import java.io.*; -import java.util.*; -import java.util.zip.*; -import java.net.*; - -import org.apache.fop.apps.*; - -import com.icl.saxon.TransformerFactoryImpl; - -/** - * Gradle Docbook plugin implementation. - *

- * Creates three tasks: docbookHtml, docbookHtmlSingle and docbookPdf. Each task takes a single File on - * which it operates. - */ -class DocbookPlugin implements Plugin { - public void apply(Project project) { - // Add the plugin tasks to the project - Task docbookHtml = project.tasks.add('docbookHtml', DocbookHtml.class); - docbookHtml.setDescription('Generates chunked docbook html output'); - - Task docbookHtmlSingle = project.tasks.add('docbookHtmlSingle', Docbook.class); - docbookHtmlSingle.setDescription('Generates single page docbook html output') - docbookHtmlSingle.suffix = '-single' - - Task docbookFoPdf = project.tasks.add("docbookFoPdf", DocbookFoPdf.class); - docbookFoPdf.setDescription('Generates PDF output'); - docbookFoPdf.extension = 'fo' - - Task docbook = project.tasks.add("docbook", DefaultTask.class); - docbook.dependsOn (docbookHtml, docbookHtmlSingle, docbookFoPdf) - } -} - -/** - */ -public class Docbook extends DefaultTask { - - @Input - String extension = 'html'; - - @Input - String suffix = ''; - - @Input - boolean XIncludeAware = true; - - @Input - boolean highlightingEnabled = true; - - String admonGraphicsPath; - - String imgSrcPath; - - @InputDirectory - File sourceDirectory = new File(project.getProjectDir(), "src/docbook"); - - @Input - String sourceFileName; - - @InputFile - File stylesheet; - - @OutputDirectory - File docsDir = new File(project.getBuildDir(), "docs"); - - @TaskAction - public final void transform() { - SAXParserFactory factory = new org.apache.xerces.jaxp.SAXParserFactoryImpl(); - factory.setXIncludeAware(XIncludeAware); - docsDir.mkdirs(); - - File srcFile = new File(filterDocbookSources(sourceDirectory), sourceFileName); - String outputFilename = srcFile.getName().substring(0, srcFile.getName().length() - 4) + suffix + '.' + extension; - - File outputFile = new File(getDocsDir(), outputFilename); - - Result result = new StreamResult(outputFile.getAbsolutePath()); - CatalogResolver resolver = new CatalogResolver(createCatalogManager()); - InputSource inputSource = new InputSource(srcFile.getAbsolutePath()); - - XMLReader reader = factory.newSAXParser().getXMLReader(); - reader.setEntityResolver(resolver); - TransformerFactory transformerFactory = new TransformerFactoryImpl(); - transformerFactory.setURIResolver(resolver); - URL url = stylesheet.toURL(); - Source source = new StreamSource(url.openStream(), url.toExternalForm()); - Transformer transformer = transformerFactory.newTransformer(source); - - if (highlightingEnabled) { - File highlightingDir = new File(getProject().getBuildDir(), "highlighting"); - if (!highlightingDir.exists()) { - highlightingDir.mkdirs(); - extractHighlightFiles(highlightingDir); - } - - transformer.setParameter("highlight.xslthl.config", new File(highlightingDir, "xslthl-config.xml").toURI().toURL()); - } - - if (admonGraphicsPath != null) { - transformer.setParameter("admon.graphics", "1"); - transformer.setParameter("admon.graphics.path", admonGraphicsPath); - } - - if (imgSrcPath != null) { - transformer.setParameter("img.src.path", imgSrcPath); - } - - preTransform(transformer, srcFile, outputFile); - - transformer.transform(new SAXSource(reader, inputSource), result); - - postTransform(outputFile); - } - - /** - * @param sourceDir directory of unfiltered sources - * @return directory of filtered sources - * @author Chris Beams - */ - private File filterDocbookSources(File sourceDir) { - def docbookWorkDir = new File("${project.buildDir}/reference-work") - - docbookWorkDir.mkdirs() - - // copy everything but springsecurity.xml - project.copy { - into(docbookWorkDir) - from(sourceDir) { exclude '**/springsecurity.xml' } - } - // copy index.xml and expand ${...} variables along the way - // e.g.: ${version} needs to be replaced in the header - project.copy { - into(docbookWorkDir) - from(sourceDir) { include '**/springsecurity.xml' } - expand(version: "${project.version}") - } - - return docbookWorkDir - } - - private void extractHighlightFiles(File toDir) { - URLClassLoader cl = (URLClassLoader) getClass().getClassLoader(); - URL[] urls = cl.getURLs(); - URL docbookZip = null; - - for (URL url : urls) { - if (url.toString().contains("docbook-xsl-")) { - docbookZip = url; - break; - } - } - - if (docbookZip == null) { - throw new GradleException("Docbook zip file not found"); - } - - ZipFile zipFile = new ZipFile(new File(docbookZip.toURI())); - - Enumeration e = zipFile.entries(); - while (e.hasMoreElements()) { - ZipEntry ze = (ZipEntry) e.nextElement(); - if (ze.getName().matches(".*/highlighting/.*\\.xml")) { - String filename = ze.getName().substring(ze.getName().lastIndexOf("/highlighting/") + 14); - copyFile(zipFile.getInputStream(ze), new File(toDir, filename)); - } - } - } - - private void copyFile(InputStream source, File destFile) { - destFile.createNewFile(); - FileOutputStream to = null; - try { - to = new FileOutputStream(destFile); - byte[] buffer = new byte[4096]; - int bytesRead; - - while ((bytesRead = source.read(buffer)) > 0) { - to.write(buffer, 0, bytesRead); - } - } finally { - if (source != null) { - source.close(); - } - if (to != null) { - to.close(); - } - } - } - - protected void preTransform(Transformer transformer, File sourceFile, File outputFile) { - } - - protected void postTransform(File outputFile) { - } - - private CatalogManager createCatalogManager() { - CatalogManager manager = new CatalogManager(); - manager.setIgnoreMissingProperties(true); - ClassLoader classLoader = this.getClass().getClassLoader(); - StringBuilder builder = new StringBuilder(); - String docbookCatalogName = "docbook/catalog.xml"; - URL docbookCatalog = classLoader.getResource(docbookCatalogName); - - if (docbookCatalog == null) { - throw new IllegalStateException("Docbook catalog " + docbookCatalogName + " could not be found in " + classLoader); - } - - builder.append(docbookCatalog.toExternalForm()); - - Enumeration enumeration = classLoader.getResources("/catalog.xml"); - while (enumeration.hasMoreElements()) { - builder.append(';'); - URL resource = (URL) enumeration.nextElement(); - builder.append(resource.toExternalForm()); - } - String catalogFiles = builder.toString(); - manager.setCatalogFiles(catalogFiles); - return manager; - } -} - -/** - */ -class DocbookHtml extends Docbook { - - @Override - protected void preTransform(Transformer transformer, File sourceFile, File outputFile) { - String rootFilename = outputFile.getName(); - rootFilename = rootFilename.substring(0, rootFilename.lastIndexOf('.')); - transformer.setParameter("root.filename", rootFilename); - transformer.setParameter("base.dir", outputFile.getParent() + File.separator); - } -} - -/** - */ -class DocbookFoPdf extends Docbook { - - /** - * From the FOP usage guide - */ - @Override - protected void postTransform(File foFile) { - FopFactory fopFactory = FopFactory.newInstance(); - - OutputStream out = null; - final File pdfFile = getPdfOutputFile(foFile); - logger.debug("Transforming 'fo' file "+ foFile + " to PDF: " + pdfFile); - - try { - out = new BufferedOutputStream(new FileOutputStream(pdfFile)); - - Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out); - - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTransformer(); - - Source src = new StreamSource(foFile); - - Result res = new SAXResult(fop.getDefaultHandler()); - - transformer.transform(src, res); - } finally { - if (out != null) { - out.close(); - } - } - -/* if (!foFile.delete()) { - logger.warn("Failed to delete 'fo' file " + foFile); - }*/ - } - - private File getPdfOutputFile(File foFile) { - String name = foFile.getAbsolutePath(); - return new File(name.substring(0, name.length() - 2) + "pdf"); - } -} diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/docbook.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/docbook.properties deleted file mode 100644 index 5fecd7333b..0000000000 --- a/buildSrc/src/main/resources/META-INF/gradle-plugins/docbook.properties +++ /dev/null @@ -1 +0,0 @@ -implementation-class=docbook.DocbookPlugin \ No newline at end of file diff --git a/core/pom.xml b/core/pom.xml index c455bf7950..365544c67b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -200,6 +200,12 @@ 1.6.1 test + + org.springframework.security + spring-security-crypto + 3.2.0.CI-SNAPSHOT + test + org.springframework spring-test diff --git a/docs/docs.gradle b/docs/docs.gradle index 685ac7dbd6..5b2728ecd7 100644 --- a/docs/docs.gradle +++ b/docs/docs.gradle @@ -2,53 +2,42 @@ apply plugin: 'base' task docs { - dependsOn 'manual:docbook', 'faq:docbookHtmlSingle', 'apidocs' + dependsOn 'manual:reference', 'faq:referenceHtmlSingle', 'apidocs' } subprojects { apply plugin: 'base' - apply plugin: 'docbook' + apply plugin: 'docbook-reference' - docbookHtmlSingle.stylesheet = new File(projectDir, 'src/xsl/html-single-custom.xsl') + [referenceHtmlMulti, referencePdf, referenceHtmlSingle]*.sourceDir = file('src/docbook') } project('faq') { - defaultTasks 'docbookHtmlSingle' - [docbookHtml, docbookFoPdf, docbookHtmlSingle]*.sourceFileName = 'faq.xml' - docbookHtmlSingle.suffix = '' + defaultTasks 'referenceHtmlSingle' + referenceHtmlSingle.stylesheet = 'html-single-custom.xsl' + [referenceHtmlMulti, referencePdf, referenceHtmlSingle]*.sourceFileName = 'faq.xml' ext.spec = copySpec { into ('faq') { - from("$buildDir/docs") + from("$buildDir/reference/htmlsingle") from("$projectDir/src/resources") } } } project('manual') { - defaultTasks 'docbookHtml', 'docbookHtmlSingle', 'docbookFoPdf' - [docbookHtml, docbookFoPdf, docbookHtmlSingle]*.sourceFileName = 'springsecurity.xml' - - docbookHtml.stylesheet = new File(projectDir, 'src/xsl/html-custom.xsl') - docbookHtmlSingle.stylesheet = new File(projectDir, 'src/xsl/html-single-custom.xsl') - docbookFoPdf.stylesheet = new File(projectDir, 'src/xsl/pdf-custom.xsl') + defaultTasks 'referenceHtmlMulti', 'referenceHtmlSingle', 'referencePdf' def imagesDir = new File(projectDir, 'src/docbook/images'); -// docbookFoPdf.admonGraphicsPath = "${imagesDir}/" - docbookFoPdf.imgSrcPath = "${projectDir}/src/docbook/" ext.spec = copySpec { into ('reference') { - from("$buildDir/docs") - from("$projectDir/src/resources") - } - into ('reference/images') { - from (imagesDir) + from("$buildDir/reference") } } } task reference (type: Copy) { - dependsOn 'manual:docbook' + dependsOn 'manual:reference' destinationDir = buildDir with(project('manual').spec) } @@ -99,7 +88,7 @@ ext.apiSpec = copySpec { } } -assemble.dependsOn = [apidocs, 'manual:docbook'] +assemble.dependsOn = [apidocs, 'manual:reference'] task docsZip(type: Zip) { dependsOn docs diff --git a/docs/faq/src/xsl/html-single-custom.xsl b/docs/faq/src/docbook/xsl/html-single-custom.xsl similarity index 100% rename from docs/faq/src/xsl/html-single-custom.xsl rename to docs/faq/src/docbook/xsl/html-single-custom.xsl diff --git a/docs/manual/src/docbook/springsecurity.xml b/docs/manual/src/docbook/index.xml similarity index 55% rename from docs/manual/src/docbook/springsecurity.xml rename to docs/manual/src/docbook/index.xml index 0188bc587c..dd0af05bbe 100644 --- a/docs/manual/src/docbook/springsecurity.xml +++ b/docs/manual/src/docbook/index.xml @@ -18,60 +18,62 @@ Preface - Spring Security provides a comprehensive security solution for J2EE-based enterprise - software applications. As you will discover as you venture through this reference guide, - we have tried to provide you a useful and highly configurable security system. - Security is an ever-moving target, and it's important to pursue a comprehensive, - system-wide approach. In security circles we encourage you to adopt "layers of - security", so that each layer tries to be as secure as possible in its own right, with - successive layers providing additional security. The "tighter" the security of each - layer, the more robust and safe your application will be. At the bottom level you'll - need to deal with issues such as transport security and system identification, in order - to mitigate man-in-the-middle attacks. Next you'll generally utilise firewalls, perhaps - with VPNs or IP security to ensure only authorised systems can attempt to connect. In - corporate environments you may deploy a DMZ to separate public-facing servers from - backend database and application servers. Your operating system will also play a - critical part, addressing issues such as running processes as non-privileged users and - maximising file system security. An operating system will usually also be configured - with its own firewall. Hopefully somewhere along the way you'll be trying to prevent - denial of service and brute force attacks against the system. An intrusion detection - system will also be especially useful for monitoring and responding to attacks, with - such systems able to take protective action such as blocking offending TCP/IP addresses - in real-time. Moving to the higher layers, your Java Virtual Machine will hopefully be - configured to minimize the permissions granted to different Java types, and then your - application will add its own problem domain-specific security configuration. Spring - Security makes this latter area - application security - much easier. - Of course, you will need to properly address all security layers mentioned above, - together with managerial factors that encompass every layer. A non-exhaustive list of - such managerial factors would include security bulletin monitoring, patching, personnel - vetting, audits, change control, engineering management systems, data backup, disaster - recovery, performance benchmarking, load monitoring, centralised logging, incident - response procedures etc. - With Spring Security being focused on helping you with the enterprise application - security layer, you will find that there are as many different requirements as there are - business problem domains. A banking application has different needs from an ecommerce - application. An ecommerce application has different needs from a corporate sales force - automation tool. These custom requirements make application security interesting, - challenging and rewarding. - Please read , in its entirety to begin with. This - will introduce you to the framework and the namespace-based configuration system with - which you can get up and running quite quickly. To get more of an understanding of how - Spring Security works, and some of the classes you might need to use, you should then - read . The remaining parts of this guide are - structured in a more traditional reference style, designed to be read on an as-required - basis. We'd also recommend that you read up as much as possible on application security - issues in general. Spring Security is not a panacea which will solve all security - issues. It is important that the application is designed with security in mind from the - start. Attempting to retrofit it is not a good idea. In particular, if you are building - a web application, you should be aware of the many potential vulnerabilities such as - cross-site scripting, request-forgery and session-hijacking which you should be taking - into account from the start. The OWASP web site (http://www.owasp.org/) maintains a top - ten list of web application vulnerabilities as well as a lot of useful reference - information. - We hope that you find this reference guide useful, and we welcome your feedback and - suggestions. - Finally, welcome to the Spring Security community. + + Spring Security provides a comprehensive security solution for J2EE-based enterprise + software applications. As you will discover as you venture through this reference guide, + we have tried to provide you a useful and highly configurable security system. + Security is an ever-moving target, and it's important to pursue a comprehensive, + system-wide approach. In security circles we encourage you to adopt "layers of + security", so that each layer tries to be as secure as possible in its own right, with + successive layers providing additional security. The "tighter" the security of each + layer, the more robust and safe your application will be. At the bottom level you'll + need to deal with issues such as transport security and system identification, in order + to mitigate man-in-the-middle attacks. Next you'll generally utilise firewalls, perhaps + with VPNs or IP security to ensure only authorised systems can attempt to connect. In + corporate environments you may deploy a DMZ to separate public-facing servers from + backend database and application servers. Your operating system will also play a + critical part, addressing issues such as running processes as non-privileged users and + maximising file system security. An operating system will usually also be configured + with its own firewall. Hopefully somewhere along the way you'll be trying to prevent + denial of service and brute force attacks against the system. An intrusion detection + system will also be especially useful for monitoring and responding to attacks, with + such systems able to take protective action such as blocking offending TCP/IP addresses + in real-time. Moving to the higher layers, your Java Virtual Machine will hopefully be + configured to minimize the permissions granted to different Java types, and then your + application will add its own problem domain-specific security configuration. Spring + Security makes this latter area - application security - much easier. + Of course, you will need to properly address all security layers mentioned above, + together with managerial factors that encompass every layer. A non-exhaustive list of + such managerial factors would include security bulletin monitoring, patching, personnel + vetting, audits, change control, engineering management systems, data backup, disaster + recovery, performance benchmarking, load monitoring, centralised logging, incident + response procedures etc. + With Spring Security being focused on helping you with the enterprise application + security layer, you will find that there are as many different requirements as there are + business problem domains. A banking application has different needs from an ecommerce + application. An ecommerce application has different needs from a corporate sales force + automation tool. These custom requirements make application security interesting, + challenging and rewarding. + Please read , in its entirety to begin with. This + will introduce you to the framework and the namespace-based configuration system with + which you can get up and running quite quickly. To get more of an understanding of how + Spring Security works, and some of the classes you might need to use, you should then + read . The remaining parts of this guide are + structured in a more traditional reference style, designed to be read on an as-required + basis. We'd also recommend that you read up as much as possible on application security + issues in general. Spring Security is not a panacea which will solve all security + issues. It is important that the application is designed with security in mind from the + start. Attempting to retrofit it is not a good idea. In particular, if you are building + a web application, you should be aware of the many potential vulnerabilities such as + cross-site scripting, request-forgery and session-hijacking which you should be taking + into account from the start. The OWASP web site (http://www.owasp.org/) maintains a top + ten list of web application vulnerabilities as well as a lot of useful reference + information. + We hope that you find this reference guide useful, and we welcome your feedback and + suggestions. + Finally, welcome to the Spring Security community. + Getting Started @@ -168,7 +170,7 @@ - +