1
0
mirror of synced 2026-07-08 20:30:04 +00:00

Compare commits

...

34 Commits

Author SHA1 Message Date
Spring Buildmaster 5a473d2712 Release version 3.1.5.RELEASE 2014-02-19 07:12:06 -08:00
Rob Winch ac6cf5396a SEC-2468: JdbcUserDetailsManager#createNewAuthentication uses null credentials 2014-02-14 17:00:07 -06:00
james 5a2e99c940 SEC-2467: Fix Small errors in itest-web's jsps 2014-01-28 16:09:09 -06:00
Rob Winch 6f3c6f9b5b SEC-2447: JdbcMutableAclServiceTests should invoke aclCache.clearCache() 2013-12-14 10:20:31 -06:00
Rob Winch 1feb38048b Update to Gradle 1.9
Necessary to work with the latest Bamboo and Artifactory Gradle updates
2013-12-05 09:08:26 -06:00
Rob Winch 905c59f599 SEC-2313: Gradle javadoc hotfix 2013-09-11 15:42:53 -07:00
Rob Winch 241e984ea4 SEC-2171: Include Information about pooling in Spring LDAP documentation 2013-08-25 11:31:05 -05:00
Rob Winch 8053cb0de7 SEC-2103: Fix tests to verify debug logging instead of info 2013-08-25 10:05:48 -05:00
Rob Winch 889bba1d67 SEC-2103: Change log of no results to debug 2013-08-24 23:40:48 -05:00
Rob Winch f9fd448d88 SEC-2139: named-security-filter are all defined and ordered correctly 2013-08-24 15:20:23 -05:00
Rob Winch 7bf6046408 SEC-2108: Fix typo in ldap section of manual 2013-08-24 15:20:23 -05:00
Guillaume Smet 5dfeea7631 SEC-2245: Cast to interface instead of implementation
Makes our life easier when we want to override the
MethodSecurityExpressionRoot.
2013-08-05 17:06:09 -05:00
Luke Taylor f42720b1b6 SEC-2175: Correct XSD docs on auto-config. 2013-06-09 14:46:56 +01:00
Rob Winch 113e28a148 Update to next dev version - 3.1.5.CI-SNAPSHOT 2013-04-29 08:47:30 -05:00
Spring Buildmaster de6bcb80b9 [artifactory-release] Next development version 2013-04-27 13:05:38 -07:00
Rob Winch 102da87080 Disable artifactoryPublish for projects without artifacts 2013-04-27 13:56:12 -05:00
Rob Winch f1ae9da55e Remove ApacheDSContainerTests successfulStartupAndShutdown since it was commented out 2013-04-25 11:17:21 -05:00
Rob Winch 94e2e0c65e SEC-2161: <ldap-server> creates unique dir for embedded LDAP 2013-04-25 11:17:21 -05:00
Rob Winch fa3a30cc20 SEC-2162: ApacheDSContainer throws RuntimeException on failure to start 2013-04-25 11:17:21 -05:00
Rob Winch ee6e6ceafb SEC-2133: Update doc from ChannelAuthenticationFilter to ChannelProcessingFilter 2013-04-25 08:51:51 -05:00
Rob Winch 095594daea SEC-2147: Deprecate .encoding.PasswordEncoding 2013-04-25 08:49:33 -05:00
Rob Winch e9215c4dc3 SEC-2087: GlobalMethodSecurityBeanDefinitionParser uses AuthenticationManager to create AuthenticationManagerDelegator 2013-04-24 17:30:51 -05:00
@fbiville 0d70c703df SEC-2138: Fix code snippet in Hierarchical Roles section
The bean definition of RoleHierarchyVoter was syntactically incorrect.
2013-02-26 09:47:02 -06:00
Rob Winch 73710bf7b8 Add CONTRIBUTING.md 2013-02-25 17:14:21 -06:00
Jean-Pierre Bergamin ca5501eb31 SEC-2118: Fixing spring and aspectj OSGi version ranges [3.2, 3.2) -> [3.2, 3.3) 2013-02-25 17:10:07 -06:00
Rob Winch c703806fa2 Revert "SEC-2078: AbstractPreAuthenticatedProcessingFilter requriesAuthentication support for non-String Principals"
This reverts commit 3fe7791266.
2012-12-06 16:16:50 -06:00
Rob Winch 67eb9821f3 Revert "SEC-2078: Updated Javadoc to reflect that updates to Principal will also trigger reauthentication"
This reverts commit ece4a0f067.
2012-12-06 16:16:33 -06:00
Rob Winch 7b93ffd5d4 SEC-2078: Updated Javadoc to reflect that updates to Principal will also trigger reauthentication 2012-12-06 09:05:21 -06:00
Rob Winch 5fa252b848 SEC-2078: AbstractPreAuthenticatedProcessingFilter requriesAuthentication support for non-String Principals
Previously, if the Principal returned by getPreAuthenticatedPrincipal was not a String,
it prevented requiresAuthentication from detecting when the Principal was the same.
This caused the need to authenticate the user for every request even when the Principal
did not change.

Now requiresAuthentication will check to see if the result of
getPreAuthenticatedPrincipal is equal to the current Authentication.getPrincipal().
2012-12-04 13:04:41 -06:00
Rob Winch 87c3c7edb9 Use AspectJMethodSecurityInterceptor in reference
Change reference to use AspectJMethodSecurityInterceptor instead of
undefined AspectJSecurityInterceptor.
2012-12-04 10:07:30 -06:00
Rob Winch 7f342f3321 SEC-2074: Update reference to use <method-security-metadata-source> 2012-12-04 10:07:30 -06:00
Rob Winch 2f6325f651 SEC-2084: AntPathRequestMatcher and RegexpRequestMatcher support request.getMethod()
Previously a NullPointerException would occur if an HttpServletRequest.getMethod()
returned null.

Now AntPathRequestMatcher and RegexpRequestMatcher will handle if the
HttpServletRequest.getMethod() returns null. While under normal circumstances,
it is unlikely for the method to be null this can occur when using
DefaultWebInvocationPrivilegeEvaluator.isAllowed(String, Authentication).
2012-12-03 15:08:37 -06:00
Rob Winch e3f53908af SEC-2072: <security:anonymous> granted-authority supports multiple authorities again 2012-11-02 16:23:37 -05:00
Rob Winch 4d1127106b Add 3.1.x suffix to eclipse projects 2012-11-02 10:00:45 -05:00
36 changed files with 616 additions and 79 deletions
+186
View File
@@ -0,0 +1,186 @@
_Have something you'd like to contribute to the framework? We welcome pull requests, but ask that you carefully read this document first to understand how best to submit them; what kind of changes are likely to be accepted; and what to expect from the Spring Security team when evaluating your submission._
_Please refer back to this document as a checklist before issuing any pull request; this will save time for everyone!_
# Similar but different
Each Spring module is slightly different than another in terms of team size, number of issues, etc. Therefore each project is managed slightly different. You will notice that this document is very similar to the [Spring Framework Contributor guidelines](https://github.com/SpringSource/spring-framework/wiki/Contributor-guidelines). However, there are some subtle differences between the two documents, so please be sure to read this document thoroughly.
# Understand the basics
Not sure what a pull request is, or how to submit one? Take a look at GitHub's excellent [help documentation first](http://help.github.com/send-pull-requests).
# Search JIRA first; create an issue if necessary
Is there already an issue that addresses your concern? Do a bit of searching in our [JIRA issue tracker](https://jira.springsource.org/browse/SEC) to see if you can find something similar. If not, please create a new issue before submitting a pull request unless the change is not a user facing issue.
# Discuss non-trivial contribution ideas with committers
If you're considering anything more than correcting a typo or fixing a minor bug , please discuss it on the [Spring Security forums](http://forum.springsource.org/forumdisplay.php?33-Security) before submitting a pull request. We're happy to provide guidance but please spend an hour or two researching the subject on your own including searching the forums for prior discussions.
# Sign the Contributor License Agreement
If you have not previously done so, please fill out and submit the SpringSource CLA form. You'll receive a token when this process is complete. Keep track of this, you may be asked for it later!
* For **Project** select _Spring Security_
* For **Project Lead** enter _Rob Winch_
* Note that emailing/postal mailing a signed copy is not necessary. Submission of the web form is all that is required.
When you've completed the web form, simply add the following in a comment on your pull request:
> I have signed and agree to the terms of the SpringSource Individual Contributor License Agreement.
You do not need to include your token/id. Please add the statement above to all future pull requests as well, simply so the Spring Security team knows immediately that this process is complete.
# Create your branch from master
Create your topic branch to be submitted as a pull request from master. The Spring team will consider your pull request for backporting on a case-by-case basis; you don't need to worry about submitting anything for backporting.
# Use short branch names
Branches used when submitting pull requests should preferably be named according to JIRA issues, e.g. 'SEC-1234'. Otherwise, use succinct, lower-case, dash (-) delimited names, such as 'fix-warnings', 'fix-typo', etc. This is important, because branch names show up in the merge commits that result from accepting pull requests, and should be as expressive and concise as possible.
#Keep commits focused
Remember each JIRA should be focused on a single item of interest since the JIRA tickets are used to produce the changelog. Since each commit should be tied to a JIRA, ensure that your commits are focused. For example, do not include an update to a transitive library in your commit unless the JIRA is to update the library. Reviewing your commits is essential before sending a pull request.
# Mind the whitespace
Please carefully follow the whitespace and formatting conventions already present in the framework.
1. Spaces, not tabs
1. Unix (LF), not dos (CRLF) line endings
1. Eliminate all trailing whitespace
1. Aim to wrap code at 120 characters, but favor readability over wrapping
1. Preserve existing formatting; i.e. do not reformat code for its own sake
1. Search the codebase using git grep and other tools to discover common naming conventions, etc.
1. Latin-1 (ISO-8859-1) encoding for Java sources; use native2ascii to convert if necessary
Whitespace management tips
1. You can use the [AnyEdit Eclipse plugin](http://marketplace.eclipse.org/content/anyedit-tools) to ensure spaces are used and to clean up trailing whitespaces.
1. Use git's pre-commit.sample hook to prevent invalid whitespace from being pushed out. You can enable it by moving ~/spring-security/.git/hooks/pre-commit.sample to ~/spring-security/.git/hooks/pre-commit and ensuring it is executable. For more information on hooks refer to [Pro Git's Pre-Commit Hook's section](http://git-scm.com/book/cs/ch7-3.html)
# Add Apache license header to all new classes
<pre>
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ...;
</pre>
# Update Apache license header to modified files as necessary
Always check the date range in the license header. For example, if you've modified a file in 2012 whose header still reads
<pre>
* Copyright 2002-2011 the original author or authors.
</pre>
then be sure to update it to 2012 appropriately
<pre>
* Copyright 2002-2012 the original author or authors.
</pre>
# Use @since tags for newly-added public API types and methods
e.g.
<pre>
/**
* ...
*
* @author First Last
* @since 3.2
* @see ...
*/
</pre>
#Submit JUnit test cases for all behavior changes
Search the codebase to find related unit tests and add additional `@Test` methods within.
1. Any new tests should end in the name Tests (note this is plural). For example, a valid name would be `FilterChainProxyTests`. An invalid name would be `FilterChainProxyTest`.
2. New test methods should not start with test. This is an old JUnit3 convention and is not necessary since the method is annotated with @Test.
# Squash commits
Use git rebase --interactive, git add --patch and other tools to "squash" multiple commits into atomic changes. In addition to the man pages for git, there are many resources online to help you understand how these tools work. Here is one: http://book.git-scm.com/4_interactive_rebasing.html.
# Use real name in git commits
Please configure git to use your real first and last name for any commits you intend to submit as pull requests. For example, this is not acceptable:
<pre>
Author: Nickname &lt;user@mail.com&gt;
</pre>
Rather, please include your first and last name, properly capitalized, as submitted against the SpringSource contributor license agreement:
<pre>
Author: First Last &lt;user@mail.com&gt;
</pre>
This helps ensure traceability against the CLA, and also goes a long way to ensuring useful output from tools like git shortlog and others.
You can configure this globally via the account admin area GitHub (useful for fork-and-edit cases); globally with
<pre>
git config --global user.name "First Last"
git config --global user.email user@mail.com
</pre>
or locally for the spring-security repository only by omitting the '--global' flag:
<pre>
cd spring-security
git config user.name "First Last"
git config user.email user@mail.com
</pre>
# Format commit messages
<pre>
SEC-1234: Short (50 chars or less) summary of changes
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, preceded by a
single space, with blank lines in between, but conventions vary here
</pre>
1. The commit subject should start with the associated jira issue followed by a : as shown in the example above
2. Keep the subject line to 50 characters or less if possible
3. Do not end the subject line with a period
4. In the body of the commit message, explain how things worked before this commit, what has changed, and how things work now
# Run all tests prior to submission
<pre>
cd spring-security
./gradlew clean build integrationTest
</pre>
# Submit your pull request
Subject line:
Follow the same conventions for pull request subject lines as mentioned above for commit message subject lines.
In the body:
1. Explain your use case. What led you to submit this change? Why were existing mechanisms in the framework insufficient? Make a case that this is a general-purpose problem and that yours is a general-purpose solution, etc
2. Add any additional information and ask questions; start a conversation, or continue one from JIRA
3. Mention the JIRA issue ID
4. Also mention that you have submitted the CLA as described above
Note that for pull requests containing a single commit, GitHub will default the subject line and body of the pull request to match the subject line and body of the commit message. This is fine, but please also include the items above in the body of the request.
# Mention your pull request on the associated JIRA issue
Add a comment to the associated JIRA issue(s) linking to your new pull request.
# Expect discussion and rework
The Spring team takes a very conservative approach to accepting contributions to the framework. This is to keep code quality and stability as high as possible, and to keep complexity at a minimum. Your changes, if accepted, may be heavily modified prior to merging. You will retain "Author:" attribution for your Git commits granted that the bulk of your changes remain intact. You may be asked to rework the submission for style (as explained above) and/or substance. Again, we strongly recommend discussing any serious submissions with the Spring Framework team prior to engaging in serious development work.
Note that you can always force push (git push -f) reworked / rebased commits against the branch used to submit your pull request. i.e. you do not need to issue a new pull request when asked to make changes.
@@ -105,6 +105,7 @@ public class JdbcMutableAclServiceTests extends AbstractTransactionalJUnit4Sprin
jdbcTemplate.execute("drop table acl_object_identity");
jdbcTemplate.execute("drop table acl_class");
jdbcTemplate.execute("drop table acl_sid");
aclCache.clearCache();
}
@Test
+14 -1
View File
@@ -1,3 +1,12 @@
buildscript {
repositories {
maven { url "http://repo.springsource.org/plugins-release" }
}
dependencies {
classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1')
}
}
apply plugin: 'base'
description = 'Spring Security'
@@ -20,6 +29,10 @@ ext.itestProjects = subprojects.findAll { project -> project.name.startsWith('it
ext.coreModuleProjects = javaProjects - sampleProjects - itestProjects
ext.aspectjProjects = [project(':spring-security-aspects'), project(':spring-security-samples-aspectj')]
configure(subprojects - coreModuleProjects) {
tasks.findByPath("artifactoryPublish")?.enabled = false
}
configure(javaProjects) {
apply from: "$rootDir/gradle/javaprojects.gradle"
}
@@ -75,5 +88,5 @@ artifacts {
apply from: "$rootDir/gradle/ide-integration.gradle"
task wrapper(type: Wrapper) {
gradleVersion = '1.2'
gradleVersion = '1.9'
}
@@ -11,6 +11,7 @@ import org.gradle.api.GradleException
import org.gradle.plugins.ide.eclipse.GenerateEclipseProject
import org.gradle.plugins.ide.eclipse.GenerateEclipseClasspath
import org.gradle.plugins.ide.eclipse.EclipsePlugin
import org.gradle.plugins.ide.eclipse.model.BuildCommand
import org.gradle.plugins.ide.eclipse.model.ProjectDependency
@@ -37,21 +38,26 @@ class AspectJPlugin implements Plugin<Project> {
project.configurations.add('aspectpath')
}
project.tasks.add(name: 'compileJava', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
project.tasks.add(name: 'compileAspect', overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
dependsOn project.configurations*.getTaskDependencyFromProjectDependency(true, "compileJava")
dependsOn project.processResources
sourceSet = project.sourceSets.main
inputs.files(sourceSet.java.srcDirs)
outputs.dir(sourceSet.output.classesDir)
aspectPath = project.configurations.aspectpath
}
project.tasks.compileJava.deleteAllActions()
project.tasks.compileJava.dependsOn project.tasks.compileAspect
project.tasks.add(name: 'compileTestJava', overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
project.tasks.add(name: 'compileTestAspect', overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
dependsOn project.processTestResources, project.compileJava, project.jar
sourceSet = project.sourceSets.test
inputs.files(sourceSet.java.srcDirs)
outputs.dir(sourceSet.output.classesDir)
aspectPath = project.files(project.configurations.aspectpath, project.jar.archivePath)
}
project.tasks.compileTestJava.deleteAllActions()
project.tasks.compileTestJava.dependsOn project.tasks.compileTestAspect
project.tasks.withType(GenerateEclipseProject) {
project.eclipse.project.file.whenMerged { p ->
@@ -63,8 +69,13 @@ class AspectJPlugin implements Plugin<Project> {
project.tasks.withType(GenerateEclipseClasspath) {
project.eclipse.classpath.file.whenMerged { classpath ->
def entries = classpath.entries.findAll { it instanceof ProjectDependency}.findAll { entry ->
def projectPath = entry.path.replaceAll('/',':')
project.rootProject.findProject(projectPath).plugins.findPlugin(AspectJPlugin)
def projectPath = entry.path.replaceAll('/','')
project.rootProject.allprojects.find{ p->
if(p.plugins.findPlugin(EclipsePlugin)) {
return p.eclipse.project.name == projectPath && p.plugins.findPlugin(AspectJPlugin)
}
false
}
}
entries.each { entry->
entry.entryAttributes.put('org.eclipse.ajdt.aspectpath','org.eclipse.ajdt.aspectpath')
@@ -534,7 +534,7 @@ final class AuthenticationConfigBuilder {
anonymousFilter = new RootBeanDefinition(AnonymousAuthenticationFilter.class);
anonymousFilter.getConstructorArgumentValues().addIndexedArgumentValue(0, key);
anonymousFilter.getConstructorArgumentValues().addIndexedArgumentValue(1, username);
anonymousFilter.getConstructorArgumentValues().addIndexedArgumentValue(2, AuthorityUtils.createAuthorityList(grantedAuthority));
anonymousFilter.getConstructorArgumentValues().addIndexedArgumentValue(2, AuthorityUtils.commaSeparatedStringToAuthorityList(grantedAuthority));
anonymousFilter.setSource(source);
RootBeanDefinition anonymousProviderBean = new RootBeanDefinition(AnonymousAuthenticationProvider.class);
@@ -1,3 +1,18 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.method;
import static org.springframework.security.config.Elements.*;
@@ -47,7 +62,6 @@ import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.Elements;
import org.springframework.security.config.authentication.AuthenticationManagerFactoryBean;
@@ -63,6 +77,7 @@ import org.w3c.dom.Element;
*
* @author Ben Alex
* @author Luke Taylor
* @author Rob Winch
* @since 2.0
*/
public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionParser {
@@ -234,7 +249,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
* expression voter if expression-based access control is enabled.
* @return
*/
@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "rawtypes" })
private String registerAccessManager(ParserContext pc, boolean jsr250Enabled, BeanDefinition expressionVoter) {
BeanDefinitionBuilder accessMgrBuilder = BeanDefinitionBuilder.rootBeanDefinition(AffirmativeBased.class);
@@ -259,7 +274,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
return id;
}
@SuppressWarnings("unchecked")
@SuppressWarnings("rawtypes")
private BeanReference registerDelegatingMethodSecurityMetadataSource(ParserContext pc, ManagedList delegates, Object source) {
RootBeanDefinition delegatingMethodSecurityMetadataSource = new RootBeanDefinition(DelegatingMethodSecurityMetadataSource.class);
delegatingMethodSecurityMetadataSource.setSource(source);
@@ -383,7 +398,7 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
if (delegate == null) {
Assert.state(beanFactory != null, "BeanFactory must be set to resolve " + authMgrBean);
try {
delegate = beanFactory.getBean(authMgrBean, ProviderManager.class);
delegate = beanFactory.getBean(authMgrBean, AuthenticationManager.class);
} catch (NoSuchBeanDefinitionException e) {
if (BeanIds.AUTHENTICATION_MANAGER.equals(e.getBeanName())) {
throw new NoSuchBeanDefinitionException(BeanIds.AUTHENTICATION_MANAGER,
@@ -292,7 +292,7 @@ http.attlist &=
## Allows a RequestMatcher instance to be used, as an alternative to pattern-matching.
attribute request-matcher-ref { xsd:token }?
http.attlist &=
## Automatically registers a login form, BASIC authentication, anonymous authentication, logout services, remember-me and servlet-api-integration. If set to "true", all of these capabilities are added (although you can still customize the configuration of each by providing the respective element). If unspecified, defaults to "false".
## A legacy attribute which automatically registers a login form, BASIC authentication and a logout URL and logout services. If unspecified, defaults to "false". We'd recommend you avoid using this and instead explicitly configure the services you require.
attribute auto-config {xsd:boolean}?
http.attlist &=
use-expressions?
@@ -739,4 +739,4 @@ position =
## The explicit position at which the custom-filter should be placed in the chain. Use if you are replacing a standard filter.
attribute position {named-security-filter}
named-security-filter = "FIRST" | "CHANNEL_FILTER" | "CONCURRENT_SESSION_FILTER" | "SECURITY_CONTEXT_FILTER" | "LOGOUT_FILTER" | "X509_FILTER" | "PRE_AUTH_FILTER" | "CAS_FILTER" | "FORM_LOGIN_FILTER" | "OPENID_FILTER" |"BASIC_AUTH_FILTER" | "SERVLET_API_SUPPORT_FILTER" | "REMEMBER_ME_FILTER" | "ANONYMOUS_FILTER" | "EXCEPTION_TRANSLATION_FILTER" | "SESSION_MANAGEMENT_FILTER" | "FILTER_SECURITY_INTERCEPTOR" | "SWITCH_USER_FILTER" | "LAST"
named-security-filter = "FIRST" | "CHANNEL_FILTER" | "SECURITY_CONTEXT_FILTER" | "CONCURRENT_SESSION_FILTER" | "LOGOUT_FILTER" | "X509_FILTER" | "PRE_AUTH_FILTER" | "CAS_FILTER" | "FORM_LOGIN_FILTER" | "OPENID_FILTER" | "LOGIN_PAGE_FILTER" | "DIGEST_AUTH_FILTER" |"BASIC_AUTH_FILTER" | "REQUEST_CACHE_FILTER" | "SERVLET_API_SUPPORT_FILTER" | "JAAS_API_SUPPORT_FILTER" | "REMEMBER_ME_FILTER" | "ANONYMOUS_FILTER" | "SESSION_MANAGEMENT_FILTER" | "EXCEPTION_TRANSLATION_FILTER" | "FILTER_SECURITY_INTERCEPTOR" | "SWITCH_USER_FILTER" | "LAST"
@@ -746,7 +746,7 @@
</xs:attribute>
<xs:attribute name="auto-config" type="xs:boolean">
<xs:annotation>
<xs:documentation>Automatically registers a login form, BASIC authentication, anonymous authentication, logout services, remember-me and servlet-api-integration. If set to "true", all of these capabilities are added (although you can still customize the configuration of each by providing the respective element). If unspecified, defaults to "false".</xs:documentation>
<xs:documentation>A legacy attribute which automatically registers a login form, BASIC authentication and a logout URL and logout services. If unspecified, defaults to "false". We'd recommend you avoid using this and instead explicitly configure the services you require.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="use-expressions" type="xs:boolean">
@@ -1632,20 +1632,24 @@
<xs:restriction base="xs:token">
<xs:enumeration value="FIRST"/>
<xs:enumeration value="CHANNEL_FILTER"/>
<xs:enumeration value="CONCURRENT_SESSION_FILTER"/>
<xs:enumeration value="SECURITY_CONTEXT_FILTER"/>
<xs:enumeration value="CONCURRENT_SESSION_FILTER"/>
<xs:enumeration value="LOGOUT_FILTER"/>
<xs:enumeration value="X509_FILTER"/>
<xs:enumeration value="PRE_AUTH_FILTER"/>
<xs:enumeration value="CAS_FILTER"/>
<xs:enumeration value="FORM_LOGIN_FILTER"/>
<xs:enumeration value="OPENID_FILTER"/>
<xs:enumeration value="LOGIN_PAGE_FILTER"/>
<xs:enumeration value="DIGEST_AUTH_FILTER"/>
<xs:enumeration value="BASIC_AUTH_FILTER"/>
<xs:enumeration value="REQUEST_CACHE_FILTER"/>
<xs:enumeration value="SERVLET_API_SUPPORT_FILTER"/>
<xs:enumeration value="JAAS_API_SUPPORT_FILTER"/>
<xs:enumeration value="REMEMBER_ME_FILTER"/>
<xs:enumeration value="ANONYMOUS_FILTER"/>
<xs:enumeration value="EXCEPTION_TRANSLATION_FILTER"/>
<xs:enumeration value="SESSION_MANAGEMENT_FILTER"/>
<xs:enumeration value="EXCEPTION_TRANSLATION_FILTER"/>
<xs:enumeration value="FILTER_SECURITY_INTERCEPTOR"/>
<xs:enumeration value="SWITCH_USER_FILTER"/>
<xs:enumeration value="LAST"/>
@@ -15,7 +15,10 @@
*/
package org.springframework.security.config.doc
import groovy.util.slurpersupport.NodeChild;
import groovy.util.slurpersupport.NodeChild
import org.springframework.security.config.http.SecurityFilters
import spock.lang.*
/**
@@ -31,10 +34,11 @@ class XsdDocumentedTests extends Specification {
@Shared File schemaDocument = new File('src/main/resources/org/springframework/security/config/spring-security-3.1.xsd')
@Shared Map<String,Element> elementNameToElement
@Shared schemaRootElement
def setupSpec() {
def rootElement = new XmlSlurper().parse(schemaDocument)
elementNameToElement = new SpringSecurityXsdParser(rootElement: rootElement).parse()
schemaRootElement = new XmlSlurper().parse(schemaDocument)
elementNameToElement = new SpringSecurityXsdParser(rootElement: schemaRootElement).parse()
appendixRoot.getMetaClass().sections = {
delegate.breadthFirst().inject([]) {result, c->
if(c.name() == 'section' && c.@id) {
@@ -55,6 +59,18 @@ class XsdDocumentedTests extends Specification {
}
}
def 'SEC-2139: named-security-filter are all defined and ordered properly'() {
setup:
def expectedFilters = (EnumSet.allOf(SecurityFilters) as List).sort { it.order }
when:
def nsf = schemaRootElement.simpleType.find { it.@name == 'named-security-filter' }
def nsfValues = nsf.children().children().collect { c ->
Enum.valueOf(SecurityFilters, c.@value.toString())
}
then:
expectedFilters == nsfValues
}
/**
* This will check to ensure that the expected number of xsd documents are found to ensure that we are validating
* against the current xsd document. If this test fails, all that is needed is to update the schemaDocument
@@ -212,6 +212,23 @@ class MiscHttpConfigTests extends AbstractHttpConfigTests {
'anonymity' == filter.authorities[0].authority
}
def anonymousSupportsMultipleGrantedAuthorities() {
xml.http {
'form-login'()
'anonymous'(username: 'joe', 'granted-authority':'ROLE_INVITADO,ROLE_PROFILE_INVITADO,ROLE_GRUPO_PUBLICO', key: 'customKey')
}
createAppContext()
AnonymousAuthenticationFilter filter = getFilter(AnonymousAuthenticationFilter);
def providers = appContext.getBeansOfType(AuthenticationManager).values()*.providers.flatten()
expect:
'customKey' == providers.find { it instanceof AnonymousAuthenticationProvider }.key
'customKey' == filter.key
'joe' == filter.principal
['ROLE_INVITADO','ROLE_PROFILE_INVITADO','ROLE_GRUPO_PUBLICO'] == filter.authorities*.authority
}
def httpMethodMatchIsSupported() {
httpAutoConfig {
interceptUrl '/secure*', 'DELETE', 'ROLE_SUPERVISOR'
@@ -10,9 +10,11 @@ import org.junit.After;
import org.junit.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.security.access.AccessDeniedException;
@@ -29,11 +31,13 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter;
import org.springframework.security.access.vote.AffirmativeBased;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.ConfigTestUtils;
import org.springframework.security.config.PostProcessedMockUserDetailsService;
import org.springframework.security.config.util.InMemoryXmlApplicationContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -368,6 +372,52 @@ public class GlobalMethodSecurityBeanDefinitionParserTests {
foo.foo(new SecurityConfig("A"));
}
@Test
public void supportsCustomAuthenticationManager() throws Exception {
setContext(
"<b:bean id='target' class='" + ConcreteFoo.class.getName() + "'/>" +
"<method-security-metadata-source id='mds'>" +
" <protect method='"+ Foo.class.getName() + ".foo' access='ROLE_ADMIN'/>" +
"</method-security-metadata-source>" +
"<global-method-security pre-post-annotations='enabled' metadata-source-ref='mds' authentication-manager-ref='customAuthMgr'/>" +
"<b:bean id='customAuthMgr' class='org.springframework.security.config.method.GlobalMethodSecurityBeanDefinitionParserTests$CustomAuthManager'>" +
" <b:constructor-arg value='authManager'/>" +
"</b:bean>" +
AUTH_PROVIDER_XML
);
SecurityContextHolder.getContext().setAuthentication(bob);
Foo foo = (Foo) appContext.getBean("target");
try {
foo.foo(new SecurityConfig("A"));
fail("Bob can't invoke admin methods");
} catch (AccessDeniedException expected) {
}
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("admin", "password"));
foo.foo(new SecurityConfig("A"));
}
static class CustomAuthManager implements AuthenticationManager, ApplicationContextAware {
private String beanName;
private AuthenticationManager authenticationManager;
CustomAuthManager(String beanName) {
this.beanName = beanName;
}
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
return authenticationManager.authenticate(authentication);
}
/* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.authenticationManager = applicationContext.getBean(beanName,AuthenticationManager.class);
}
}
private void setContext(String context) {
appContext = new InMemoryXmlApplicationContext(context);
}
@@ -17,7 +17,6 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.access.PermissionCacheOptimizer;
import org.springframework.security.access.expression.AbstractSecurityExpressionHandler;
import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.access.expression.SecurityExpressionOperations;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.Authentication;
@@ -153,6 +152,6 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr
}
public void setReturnObject(Object returnObject, EvaluationContext ctx) {
((MethodSecurityExpressionRoot)ctx.getRootObject().getValue()).setReturnObject(returnObject);
((MethodSecurityExpressionOperations)ctx.getRootObject().getValue()).setReturnObject(returnObject);
}
}
@@ -20,7 +20,12 @@ package org.springframework.security.authentication.encoding;
* Interface for performing authentication operations on a password.
*
* @author colin sampaleanu
* @deprecated It is recommended to use
* {@link org.springframework.security.crypto.password.PasswordEncoder}
* instead which better accommodates best practice of randomly
* generated salt that is included with the password.
*/
@Deprecated
public interface PasswordEncoder {
//~ Methods ========================================================================================================
@@ -221,7 +221,7 @@ public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsMa
UserDetails user = loadUserByUsername(currentAuth.getName());
UsernamePasswordAuthenticationToken newAuthentication =
new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
newAuthentication.setDetails(currentAuth.getDetails());
return newAuthentication;
@@ -168,7 +168,7 @@ public class JdbcUserDetailsManagerTests {
Authentication newAuth = SecurityContextHolder.getContext().getAuthentication();
assertEquals("joe", newAuth.getName());
assertEquals(currentAuth.getDetails(), newAuth.getDetails());
assertEquals("newPassword", newAuth.getCredentials());
assertNull(newAuth.getCredentials());
assertFalse(cache.getUserMap().containsKey("joe"));
}
@@ -302,6 +302,15 @@ public class JdbcUserDetailsManagerTests {
assertEquals(0, template.queryForList(SELECT_JOE_AUTHORITIES_SQL).size());
}
// SEC-2166
@Test
public void createNewAuthenticationUsesNullPasswordToKeepPassordsSave() {
insertJoe();
UsernamePasswordAuthenticationToken currentAuth = new UsernamePasswordAuthenticationToken("joe",null, AuthorityUtils.createAuthorityList("ROLE_USER"));
Authentication updatedAuth = manager.createNewAuthentication(currentAuth, "new");
assertNull(updatedAuth.getCredentials());
}
private Authentication authenticateJoe() {
UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken("joe","password", joe.getAuthorities());
@@ -494,7 +494,7 @@
interested in and to configure how they should be handled. It is used to construct
the <interfacename>FilterInvocationSecurityMetadataSource</interfacename> used by
the <classname>FilterSecurityInterceptor</classname>. It is also responsible for
configuring a <classname>ChannelAuthenticationFilter</classname> if particular URLs
configuring a <classname>ChannelProcessingFilter</classname> if particular URLs
need to be accessed by HTTPS, for example. When matching the specified patterns
against an incoming request, the matching is done in the order in which the elements
are declared. So the most specific matches patterns should come first and the most
@@ -544,7 +544,7 @@
Alternatively the value <quote>any</quote> can be used when there is no
preference. If this attribute is present on any
<literal>&lt;intercept-url&gt;</literal> element, then a
<classname>ChannelAuthenticationFilter</classname> will be added to the filter
<classname>ChannelProcessingFilter</classname> will be added to the filter
stack and its additional dependencies added to the application
context.<!--See the chapter on <link
xlink:href="#channel-security-config">channel security</link> for an example
@@ -314,7 +314,7 @@ boolean supports(Class clazz);
<programlisting language="xml"><![CDATA[
<bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
<constructor-arg ref="roleHierarchy" />
</class>
</bean>
<bean id="roleHierarchy"
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
@@ -22,6 +22,11 @@
don't use any third-party LDAP libraries (Mozilla, JLDAP etc.) in the LDAP provider, but
extensive use is made of Spring LDAP, so some familiarity with that project may be
useful if you plan on adding your own customizations.</para>
<para>When using LDAP authentication, it is important to ensure that you configure LDAP connection
pooling properly. If you are unfamiliar with how to do this, you can refer to the
<uri xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/config.html">Java LDAP
documentation</uri>.</para>
</section>
<section>
<info>
@@ -410,7 +415,7 @@ public interface UserDetailsContextMapper {
<para>By default, the user authorities are obtained from the <literal>memberOf</literal>
attribute values of the user entry. The authorities allocated to the user can again
be customized using a <interfacename>UserDetailsContextMapper</interfacename>. You
can also inject a <interfacename>GrantedAuthoritiesMaper</interfacename> into the
can also inject a <interfacename>GrantedAuthoritiesMapper</interfacename> into the
provider instance to control the authorities which end up in the
<interfacename>Authentication</interfacename> object.</para>
<section>
+9 -9
View File
@@ -35,10 +35,10 @@
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="afterInvocationManager" ref="afterInvocationManager"/>
<property name="securityMetadataSource">
<value>
com.mycompany.BankManager.delete*=ROLE_SUPERVISOR
com.mycompany.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR
</value>
<sec:method-security-metadata-source>
<sec:protect method="com.mycompany.BankManager.delete*" access="ROLE_SUPERVISOR"/>
<sec:protect method="com.mycompany.BankManager.getBalance" access="ROLE_TELLER,ROLE_SUPERVISOR"/>
</sec:method-security-metadata-source>
</property>
</bean> ]]>
</programlisting></para>
@@ -64,15 +64,15 @@
configured in the Spring application context:</para>
<programlisting language="xml"><![CDATA[
<bean id="bankManagerSecurity" class=
"org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor">
"org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="afterInvocationManager" ref="afterInvocationManager"/>
<property name="securityMetadataSource">
<value>
com.mycompany.BankManager.delete*=ROLE_SUPERVISOR
com.mycompany.BankManager.getBalance=ROLE_TELLER,ROLE_SUPERVISOR
</value>
<sec:method-security-metadata-source>
<sec:protect method="com.mycompany.BankManager.delete*" access="ROLE_SUPERVISOR"/>
<sec:protect method="com.mycompany.BankManager.getBalance" access="ROLE_TELLER,ROLE_SUPERVISOR"/>
</sec:method-security-metadata-source>
</property>
</bean>]]> </programlisting>
<para>As you can see, aside from the class name, the
+1 -1
View File
@@ -1 +1 @@
version=3.1.4.CI-SNAPSHOT
version=3.1.5.RELEASE
+7 -5
View File
@@ -1,10 +1,12 @@
apply plugin: 'idea'
configure(javaProjects) {
configure(allprojects) {
apply plugin: 'idea'
apply plugin: 'eclipse-wtp'
eclipse.classpath.downloadSources = true
eclipse.project.name = "${project.name}-3.1.x"
}
configure(javaProjects) {
eclipse.classpath.downloadSources = true
// GRADLE-1116
project.eclipse.classpath.file.whenMerged { classpath ->
@@ -49,7 +51,7 @@ project(':spring-security-samples-aspectj') {
doLast {
def classpath = new XmlParser().parse(srcFile)
classpath.classpathentry.findAll{ it.@path == '/spring-security-aspects' }.each { node ->
classpath.classpathentry.findAll{ it.@path.startsWith('/spring-security-aspects') }.each { node ->
if(node.children().size() == 0) {
def attrs = new Node(node,'attributes')
def adjtAttr = new Node(attrs,'attributes',[name: 'org.eclipse.ajdt.aspectpath', value: 'org.eclipse.ajdt.aspectpath'])
+7 -6
View File
@@ -1,4 +1,5 @@
apply plugin: 'java'
apply plugin: 'javadocHotfix'
apply plugin: 'eclipse'
sourceCompatibility = 1.5
@@ -15,13 +16,13 @@ ext.hsqlVersion = '1.8.0.10'
ext.slf4jVersion = '1.6.1'
ext.logbackVersion = '0.9.29'
ext.cglibVersion = '2.2'
ext.powerMockVersion = '1.4.12'
ext.powerMockVersion = '1.5.1'
ext.bundlorProperties = [
version: version,
secRange: "[$version, 3.2.0)",
springRange: "[$springVersion, 3.2.0)",
aspectjRange: '[1.6.0, 1.7.0)',
secRange: "[$version, 3.3.0)",
springRange: "[$springVersion, 3.3.0)",
aspectjRange: '[1.6.0, 1.8.0)',
casRange: '[3.1.1, 3.2.0)',
cloggingRange: '[1.0.4, 2.0.0)',
ehcacheRange: '[1.4.1, 2.5.0)',
@@ -78,8 +79,8 @@ dependencies {
exclude(group: 'commons-logging', module: 'commons-logging')
}
testCompile 'junit:junit:4.7',
'org.mockito:mockito-core:1.8.5',
testCompile 'junit:junit:4.10',
'org.mockito:mockito-core:1.9.5',
"org.springframework:spring-test:$springVersion"
// Use slf4j/logback for logging
Binary file not shown.
+2 -2
View File
@@ -1,6 +1,6 @@
#Fri Sep 21 14:16:44 CDT 2012
#Thu Dec 05 08:38:26 CST 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.2-bin.zip
distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-bin.zip
Vendored
+2 -2
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
##############################################################################
##
@@ -7,7 +7,7 @@
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS="-Xmx1024M -XX:MaxPermSize=256M"
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
Vendored
+1 -1
View File
@@ -9,7 +9,7 @@
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=-Xmx1024M -XX:MaxPermSize=256M
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
@@ -3,15 +3,13 @@
<body>
<h1>Authentication Tag Test Page</h1>
<p>
<ul>
<li>This is the authentication name: <sec:authentication property="name"/></li>
<li>This is the principal.username: <sec:authentication property="principal.username"/></li>
<li>This is the unescaped authentication name: <sec:authentication property="name" htmlEscape="false"/></li>
<li>This is the unescaped principal.username: <sec:authentication property="principal.username" htmlEscape="false"/></li>
</ul
</p>
</ul>
</body>
</html>
+4 -1
View File
@@ -7,6 +7,9 @@
<title>A secure page</title>
</head>
<body>
<jsp:include page="secure1body.jsp?x=1&y=2"/>
<jsp:include page="secure1body.jsp">
<jsp:param name="x" value="1" />
<jsp:param name="y" value="2" />
</jsp:include>
</body>
</html>
@@ -1,26 +1,69 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap.server;
import org.apache.directory.shared.ldap.name.LdapDN;
import static junit.framework.Assert.fail;
import org.junit.Test;
/**
* Useful for debugging the container by itself.
*
* @author Luke Taylor
* @author Rob Winch
* @since 3.0
*/
public class ApacheDSContainerTests {
// SEC-2162
@Test
public void successfulStartupAndShutdown() throws Exception {
LdapDN people = new LdapDN("ou=people,dc=springframework,dc=org");
people.toString();
public void failsToStartThrowsException() throws Exception {
ApacheDSContainer server1 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
ApacheDSContainer server2 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
try {
server1.afterPropertiesSet();
try {
server2.afterPropertiesSet();
fail("Expected Exception");
} catch(RuntimeException success) {}
} finally {
try {
server1.destroy();
}catch(Throwable t) {}
try {
server2.destroy();
}catch(Throwable t) {}
}
}
// ApacheDSContainer server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
// server.afterPropertiesSet();
//
// server.getService().getAdminSession().lookup(people);
//
// server.stop();
// SEC-2161
@Test
public void multipleInstancesSimultanciously() throws Exception {
ApacheDSContainer server1 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
ApacheDSContainer server2 = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
try {
server1.afterPropertiesSet();
server2.afterPropertiesSet();
} finally {
try {
server1.destroy();
}catch(Throwable t) {}
try {
server2.destroy();
}catch(Throwable t) {}
}
}
}
@@ -1,8 +1,22 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ldap.server;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
@@ -50,6 +64,7 @@ import org.springframework.util.Assert;
* framework public API.
*
* @author Luke Taylor
* @author Rob Winch
*/
public class ApacheDSContainer implements InitializingBean, DisposableBean, Lifecycle, ApplicationContextAware {
private final Log logger = LogFactory.getLog(getClass());
@@ -103,7 +118,7 @@ public class ApacheDSContainer implements InitializingBean, DisposableBean, Life
String apacheWorkDir = System.getProperty("apacheDSWorkDir");
if (apacheWorkDir == null) {
apacheWorkDir = System.getProperty("java.io.tmpdir") + File.separator + "apacheds-spring-security";
apacheWorkDir = createTempDirectory("apacheds-spring-security-");
}
setWorkingDirectory(new File(apacheWorkDir));
@@ -162,8 +177,7 @@ public class ApacheDSContainer implements InitializingBean, DisposableBean, Life
service.startup();
server.start();
} catch (Exception e) {
logger.error("Server startup failed ", e);
return;
throw new RuntimeException("Server startup failed", e);
}
try {
@@ -252,6 +266,22 @@ public class ApacheDSContainer implements InitializingBean, DisposableBean, Life
}
}
private String createTempDirectory(String prefix) throws IOException {
String parentTempDir = System.getProperty("java.io.tmpdir");
String fileNamePrefix = prefix + System.nanoTime();
String fileName = fileNamePrefix;
for(int i=0;i<1000;i++) {
File tempDir = new File(parentTempDir, fileName);
if(!tempDir.exists()) {
return tempDir.getAbsolutePath();
}
fileName = fileNamePrefix + "~" + i;
}
throw new IOException("Failed to create a temporary directory for file at " + new File(parentTempDir, fileNamePrefix));
}
private boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
@@ -91,8 +91,8 @@ public class JdbcTokenRepositoryImpl extends JdbcDaoSupport implements Persisten
}
}, seriesId);
} catch(EmptyResultDataAccessException zeroResults) {
if(logger.isInfoEnabled()) {
logger.info("Querying token for series '" + seriesId + "' returned no results.", zeroResults);
if(logger.isDebugEnabled()) {
logger.debug("Querying token for series '" + seriesId + "' returned no results.", zeroResults);
}
}catch(IncorrectResultSizeDataAccessException moreThanOne) {
logger.error("Querying token for series '" + seriesId + "' returned more than one value. Series" +
@@ -1,3 +1,15 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.security.web.util;
import javax.servlet.http.HttpServletRequest;
@@ -23,6 +35,7 @@ import org.springframework.util.StringUtils;
* for this class for comprehensive information on the syntax used.
*
* @author Luke Taylor
* @author Rob Winch
* @since 3.1
*
* @see org.springframework.util.AntPathMatcher
@@ -80,7 +93,7 @@ public final class AntPathRequestMatcher implements RequestMatcher {
* {@code servletPath} + {@code pathInfo} of the request.
*/
public boolean matches(HttpServletRequest request) {
if (httpMethod != null && httpMethod != HttpMethod.valueOf(request.getMethod())) {
if (httpMethod != null && request.getMethod() != null && httpMethod != HttpMethod.valueOf(request.getMethod())) {
if (logger.isDebugEnabled()) {
logger.debug("Request '" + request.getMethod() + " " + getRequestPath(request) + "'"
+ " doesn't match '" + httpMethod + " " + pattern);
@@ -1,3 +1,15 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.security.web.util;
import java.util.regex.Pattern;
@@ -19,6 +31,7 @@ import org.springframework.util.StringUtils;
* argument.
*
* @author Luke Taylor
* @author Rob Winch
* @since 3.1
*/
public final class RegexRequestMatcher implements RequestMatcher {
@@ -61,7 +74,7 @@ public final class RegexRequestMatcher implements RequestMatcher {
* @return true if the pattern matches the URL, false otherwise.
*/
public boolean matches(HttpServletRequest request) {
if (httpMethod != null && httpMethod != HttpMethod.valueOf(request.getMethod())) {
if (httpMethod != null && request.getMethod() != null && httpMethod != HttpMethod.valueOf(request.getMethod())) {
return false;
}
@@ -123,12 +123,12 @@ public class JdbcTokenRepositoryImplTests {
// SEC-1964
@Test
public void retrievingTokenWithNoSeriesReturnsNull() {
when(logger.isInfoEnabled()).thenReturn(true);
when(logger.isDebugEnabled()).thenReturn(true);
assertNull(repo.getTokenForSeries("missingSeries"));
verify(logger).isInfoEnabled();
verify(logger).info(eq("Querying token for series 'missingSeries' returned no results."),
verify(logger).isDebugEnabled();
verify(logger).debug(eq("Querying token for series 'missingSeries' returned no results."),
any(EmptyResultDataAccessException.class));
verifyNoMoreInteractions(logger);
}
@@ -1,12 +1,27 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.security.web.util;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.*;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
/**
* @author Luke Taylor
* @author Rob Winch
*/
public class AntPathRequestMatcherTests {
@@ -46,6 +61,39 @@ public class AntPathRequestMatcherTests {
assertTrue(matcher.matches(createRequest("/blah/aaa/blah/bbb")));
}
@Test
public void requestHasNullMethodMatches() {
AntPathRequestMatcher matcher = new AntPathRequestMatcher("/something/*", "GET");
MockHttpServletRequest request = createRequest("/something/here");
request.setMethod(null);
assertTrue(matcher.matches(request));
}
// SEC-2084
@Test
public void requestHasNullMethodNoMatch() {
AntPathRequestMatcher matcher = new AntPathRequestMatcher("/something/*", "GET");
MockHttpServletRequest request = createRequest("/nomatch");
request.setMethod(null);
assertFalse(matcher.matches(request));
}
@Test
public void requestHasNullMethodAndNullMatcherMatches() {
AntPathRequestMatcher matcher = new AntPathRequestMatcher("/something/*");
MockHttpServletRequest request = createRequest("/something/here");
request.setMethod(null);
assertTrue(matcher.matches(request));
}
@Test
public void requestHasNullMethodAndNullMatcherNoMatch() {
AntPathRequestMatcher matcher = new AntPathRequestMatcher("/something/*");
MockHttpServletRequest request = createRequest("/nomatch");
request.setMethod(null);
assertFalse(matcher.matches(request));
}
@Test
public void exactMatchOnlyMatchesIdenticalPath() throws Exception {
AntPathRequestMatcher matcher = new AntPathRequestMatcher("/login.html");
@@ -1,3 +1,15 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.springframework.security.web.util;
import static org.junit.Assert.*;
@@ -7,6 +19,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
/**
* @author Luke Taylor
* @author Rob Winch
*/
public class RegexRequestMatcherTests {
@@ -40,4 +53,46 @@ public class RegexRequestMatcherTests {
assertTrue(matcher.matches(request));
}
@Test
public void requestHasNullMethodMatches() {
RegexRequestMatcher matcher = new RegexRequestMatcher("/something/.*", "GET");
MockHttpServletRequest request = createRequest("/something/here");
request.setMethod(null);
assertTrue(matcher.matches(request));
}
// SEC-2084
@Test
public void requestHasNullMethodNoMatch() {
RegexRequestMatcher matcher = new RegexRequestMatcher("/something/.*", "GET");
MockHttpServletRequest request = createRequest("/nomatch");
request.setMethod(null);
assertFalse(matcher.matches(request));
}
@Test
public void requestHasNullMethodAndNullMatcherMatches() {
RegexRequestMatcher matcher = new RegexRequestMatcher("/something/.*", null);
MockHttpServletRequest request = createRequest("/something/here");
request.setMethod(null);
assertTrue(matcher.matches(request));
}
@Test
public void requestHasNullMethodAndNullMatcherNoMatch() {
RegexRequestMatcher matcher = new RegexRequestMatcher("/something/.*", null);
MockHttpServletRequest request = createRequest("/nomatch");
request.setMethod(null);
assertFalse(matcher.matches(request));
}
private MockHttpServletRequest createRequest(String path) {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("doesntMatter");
request.setServletPath(path);
request.setMethod("POST");
return request;
}
}