Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1a6a574ac | |||
| 979badd550 | |||
| 2263a545ea | |||
| 0d86164a49 | |||
| b78bd897cd | |||
| 055eb72d60 | |||
| f4914b2271 | |||
| 541aee8e3e | |||
| a6cab1be74 | |||
| bbfcab0c81 | |||
| 6e431e7d16 | |||
| 2eec67fe73 | |||
| 88559882e9 | |||
| 9270845a21 | |||
| 1d53dc5e5c | |||
| ac6cf5396a | |||
| 5a2e99c940 | |||
| 6f3c6f9b5b | |||
| 1feb38048b | |||
| 905c59f599 | |||
| 241e984ea4 | |||
| 8053cb0de7 | |||
| 889bba1d67 | |||
| f9fd448d88 | |||
| 7bf6046408 | |||
| 5dfeea7631 | |||
| f42720b1b6 | |||
| 113e28a148 | |||
| de6bcb80b9 | |||
| 102da87080 | |||
| f1ae9da55e | |||
| 94e2e0c65e | |||
| fa3a30cc20 | |||
| ee6e6ceafb | |||
| 095594daea | |||
| e9215c4dc3 | |||
| 0d70c703df | |||
| 73710bf7b8 | |||
| ca5501eb31 | |||
| c703806fa2 | |||
| 67eb9821f3 | |||
| 7b93ffd5d4 | |||
| 5fa252b848 | |||
| 87c3c7edb9 | |||
| 7f342f3321 | |||
| 2f6325f651 | |||
| e3f53908af | |||
| 4d1127106b |
+186
@@ -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 <user@mail.com>
|
||||
</pre>
|
||||
Rather, please include your first and last name, properly capitalized, as submitted against the SpringSource contributor license agreement:
|
||||
<pre>
|
||||
Author: First Last <user@mail.com>
|
||||
</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.
|
||||
+1
@@ -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
@@ -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')
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@ dependencies {
|
||||
"org.springframework:spring-context:$springVersion",
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-web:$springVersion",
|
||||
"org.jasig.cas.client:cas-client-core:3.1.12",
|
||||
"org.jasig.cas.client:cas-client-core:3.3.3",
|
||||
"net.sf.ehcache:ehcache:$ehcacheVersion"
|
||||
|
||||
provided 'javax.servlet:servlet-api:2.5'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,9 +49,7 @@ public class ServiceProperties implements InitializingBean {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if(!authenticateAllArtifacts) {
|
||||
Assert.hasLength(this.service, "service must be specified unless authenticateAllArtifacts is true.");
|
||||
}
|
||||
Assert.hasLength(this.service, "service cannot be empty.");
|
||||
Assert.hasLength(this.artifactParameter, "artifactParameter cannot be empty.");
|
||||
Assert.hasLength(this.serviceParameter, "serviceParameter cannot be empty.");
|
||||
}
|
||||
|
||||
+20
-3
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.security.cas.web.authentication;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -50,11 +52,13 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
|
||||
* string from containing the artifact name and value. This can
|
||||
* be created using {@link #createArtifactPattern(String)}.
|
||||
*/
|
||||
DefaultServiceAuthenticationDetails(HttpServletRequest request, Pattern artifactPattern) {
|
||||
DefaultServiceAuthenticationDetails(String casService, HttpServletRequest request, Pattern artifactPattern) throws MalformedURLException {
|
||||
super(request);
|
||||
URL casServiceUrl = new URL(casService);
|
||||
int port = getServicePort(casServiceUrl);
|
||||
final String query = getQueryString(request,artifactPattern);
|
||||
this.serviceUrl = UrlUtils.buildFullRequestUrl(request.getScheme(),
|
||||
request.getServerName(), request.getServerPort(),
|
||||
this.serviceUrl = UrlUtils.buildFullRequestUrl(casServiceUrl.getProtocol(),
|
||||
casServiceUrl.getHost(), port,
|
||||
request.getRequestURI(), query);
|
||||
}
|
||||
|
||||
@@ -128,4 +132,17 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
|
||||
Assert.hasLength(artifactParameterName);
|
||||
return Pattern.compile("&?"+Pattern.quote(artifactParameterName)+"=[^&]*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the port from the casServiceURL ensuring to return the proper value if the default port is being used.
|
||||
* @param casServiceUrl the casServerUrl to be used (i.e. "https://example.com/context/j_spring_security_cas_check")
|
||||
* @return the port that is configured for the casServerUrl
|
||||
*/
|
||||
private static int getServicePort(URL casServiceUrl) {
|
||||
int port = casServiceUrl.getPort();
|
||||
if(port == -1) {
|
||||
port = casServiceUrl.getDefaultPort();
|
||||
}
|
||||
return port;
|
||||
}
|
||||
}
|
||||
+48
-2
@@ -15,12 +15,18 @@
|
||||
*/
|
||||
package org.springframework.security.cas.web.authentication;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||
import org.springframework.security.cas.ServiceProperties;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* The {@code AuthenticationDetailsSource} that is set on the
|
||||
@@ -33,20 +39,33 @@ import org.springframework.security.cas.ServiceProperties;
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class ServiceAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest,
|
||||
ServiceAuthenticationDetails> {
|
||||
ServiceAuthenticationDetails>, ApplicationContextAware {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private final Pattern artifactPattern;
|
||||
|
||||
private ServiceProperties serviceProperties;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the default CAS artifactParameterName.
|
||||
* @deprecated Use ServiceAuthenticationDetailsSource(ServiceProperties)
|
||||
*/
|
||||
@Deprecated
|
||||
public ServiceAuthenticationDetailsSource() {
|
||||
this(ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the specified ServiceProperites and the default CAS artifactParameterName.
|
||||
*
|
||||
* @param serviceProperties The ServiceProperties to use to construct the serviceUrl.
|
||||
*/
|
||||
public ServiceAuthenticationDetailsSource(ServiceProperties serviceProperties) {
|
||||
this(serviceProperties,ServiceProperties.DEFAULT_CAS_ARTIFACT_PARAMETER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the specified artifactParameterName
|
||||
*
|
||||
@@ -54,11 +73,27 @@ public class ServiceAuthenticationDetailsSource implements AuthenticationDetails
|
||||
* the artifactParameterName that is removed from the current
|
||||
* URL. The result becomes the service url. Cannot be null and
|
||||
* cannot be an empty String.
|
||||
* @deprecated Use ServiceAuthenticationDetailsSource(ServiceProperties,String)
|
||||
*/
|
||||
public ServiceAuthenticationDetailsSource(final String artifactParameterName) {
|
||||
this.artifactPattern = DefaultServiceAuthenticationDetails.createArtifactPattern(artifactParameterName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an implementation that uses the specified artifactParameterName
|
||||
*
|
||||
* @param serviceProperties The ServiceProperties to use to construct the serviceUrl.
|
||||
* @param artifactParameterName
|
||||
* the artifactParameterName that is removed from the current
|
||||
* URL. The result becomes the service url. Cannot be null and
|
||||
* cannot be an empty String.
|
||||
*/
|
||||
public ServiceAuthenticationDetailsSource(ServiceProperties serviceProperties, String artifactParameterName) {
|
||||
Assert.notNull(serviceProperties, "serviceProperties cannot be null");
|
||||
this.serviceProperties = serviceProperties;
|
||||
this.artifactPattern = DefaultServiceAuthenticationDetails.createArtifactPattern(artifactParameterName);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
@@ -66,6 +101,17 @@ public class ServiceAuthenticationDetailsSource implements AuthenticationDetails
|
||||
* @return the {@code ServiceAuthenticationDetails} containing information about the current request
|
||||
*/
|
||||
public ServiceAuthenticationDetails buildDetails(HttpServletRequest context) {
|
||||
return new DefaultServiceAuthenticationDetails(context,artifactPattern);
|
||||
try {
|
||||
return new DefaultServiceAuthenticationDetails(serviceProperties.getService(),context,artifactPattern);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
if(serviceProperties == null) {
|
||||
serviceProperties = applicationContext.getBean(ServiceProperties.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,10 +36,13 @@ public class ServicePropertiesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allowNullServiceWhenAuthenticateAllTokens() throws Exception {
|
||||
public void nullServiceWhenAuthenticateAllTokens() throws Exception {
|
||||
ServiceProperties sp = new ServiceProperties();
|
||||
sp.setAuthenticateAllArtifacts(true);
|
||||
sp.afterPropertiesSet();
|
||||
try {
|
||||
sp.afterPropertiesSet();
|
||||
fail("Expected Exception");
|
||||
}catch(IllegalArgumentException success) {}
|
||||
sp.setAuthenticateAllArtifacts(false);
|
||||
try {
|
||||
sp.afterPropertiesSet();
|
||||
|
||||
+63
-12
@@ -18,11 +18,21 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.security.cas.ServiceProperties;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -32,9 +42,13 @@ public class DefaultServiceAuthenticationDetailsTests {
|
||||
private DefaultServiceAuthenticationDetails details;
|
||||
private MockHttpServletRequest request;
|
||||
private Pattern artifactPattern;
|
||||
private String casServiceUrl;
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
casServiceUrl = "https://localhost:8443/j_spring_security_cas";
|
||||
request = new MockHttpServletRequest();
|
||||
request.setScheme("https");
|
||||
request.setServerName("localhost");
|
||||
@@ -44,45 +58,82 @@ public class DefaultServiceAuthenticationDetailsTests {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlNullQuery() throws Exception {
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),details.getServiceUrl());
|
||||
@After
|
||||
public void cleanup() {
|
||||
if(context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketOnlyParam() {
|
||||
public void getServiceUrlNullQuery() throws Exception {
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl, request,artifactPattern);
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request), details.getServiceUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketOnlyParam() throws Exception {
|
||||
request.setQueryString("ticket=123");
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl,request,artifactPattern);
|
||||
String serviceUrl = details.getServiceUrl();
|
||||
request.setQueryString(null);
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),serviceUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketFirstMultiParam() {
|
||||
public void getServiceUrlTicketFirstMultiParam() throws Exception {
|
||||
request.setQueryString("ticket=123&other=value");
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl, request,artifactPattern);
|
||||
String serviceUrl = details.getServiceUrl();
|
||||
request.setQueryString("other=value");
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),serviceUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketLastMultiParam() {
|
||||
public void getServiceUrlTicketLastMultiParam() throws Exception {
|
||||
request.setQueryString("other=value&ticket=123");
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl,request,artifactPattern);
|
||||
String serviceUrl = details.getServiceUrl();
|
||||
request.setQueryString("other=value");
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),serviceUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlTicketMiddleMultiParam() {
|
||||
public void getServiceUrlTicketMiddleMultiParam() throws Exception {
|
||||
request.setQueryString("other=value&ticket=123&last=this");
|
||||
details = new DefaultServiceAuthenticationDetails(request,artifactPattern);
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl,request,artifactPattern);
|
||||
String serviceUrl = details.getServiceUrl();
|
||||
request.setQueryString("other=value&last=this");
|
||||
assertEquals(UrlUtils.buildFullRequestUrl(request),serviceUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlDoesNotUseHostHeader() throws Exception {
|
||||
casServiceUrl = "https://example.com/j_spring_security_cas";
|
||||
request.setServerName("evil.com");
|
||||
details = new DefaultServiceAuthenticationDetails(casServiceUrl, request,artifactPattern);
|
||||
assertEquals("https://example.com/cas-sample/secure/",details.getServiceUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlDoesNotUseHostHeaderPassivity() {
|
||||
casServiceUrl = "https://example.com/j_spring_security_cas";
|
||||
request.setServerName("evil.com");
|
||||
ServiceAuthenticationDetails details = loadServiceAuthenticationDetails("defaultserviceauthenticationdetails-passivity.xml");
|
||||
assertEquals("https://example.com/cas-sample/secure/", details.getServiceUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getServiceUrlDoesNotUseHostHeaderExplicit() {
|
||||
casServiceUrl = "https://example.com/j_spring_security_cas";
|
||||
request.setServerName("evil.com");
|
||||
ServiceAuthenticationDetails details = loadServiceAuthenticationDetails("defaultserviceauthenticationdetails-explicit.xml");
|
||||
assertEquals("https://example.com/cas-sample/secure/", details.getServiceUrl());
|
||||
}
|
||||
|
||||
private ServiceAuthenticationDetails loadServiceAuthenticationDetails(String resourceName) {
|
||||
context = new GenericXmlApplicationContext(getClass(), resourceName);
|
||||
ServiceAuthenticationDetailsSource source = context.getBean(ServiceAuthenticationDetailsSource.class);
|
||||
return source.buildDetails(request);
|
||||
}
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
|
||||
<bean id="serviceProperties"
|
||||
class="org.springframework.security.cas.ServiceProperties">
|
||||
<property name="service"
|
||||
value="https://example.com/j_spring_security_cas"/>
|
||||
<property name="sendRenew" value="false"/>
|
||||
</bean>
|
||||
<bean id="serviceProperties2"
|
||||
class="org.springframework.security.cas.ServiceProperties">
|
||||
<property name="service"
|
||||
value="https://example2.com/j_spring_security_cas"/>
|
||||
<property name="sendRenew" value="false"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource">
|
||||
<constructor-arg ref="serviceProperties"/>
|
||||
</bean>
|
||||
</beans>
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
|
||||
<bean id="serviceProperties"
|
||||
class="org.springframework.security.cas.ServiceProperties">
|
||||
<property name="service"
|
||||
value="https://example.com/j_spring_security_cas"/>
|
||||
<property name="sendRenew" value="false"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource"/>
|
||||
</beans>
|
||||
+1
-1
@@ -14,7 +14,7 @@ Import-Template:
|
||||
org.springframework.security.core.*;version="${secRange}",
|
||||
org.springframework.security.authentication.*;version="${secRange}",
|
||||
org.springframework.security.web.*;version="${secRange}",
|
||||
org.springframework.beans.factory;version="${springRange}",
|
||||
org.springframework.beans.*;version="${springRange}",
|
||||
org.springframework.context.*;version="${springRange}",
|
||||
org.springframework.dao;version="${springRange}",
|
||||
org.springframework.util;version="${springRange}",
|
||||
|
||||
@@ -52,8 +52,4 @@ dependencies {
|
||||
|
||||
test {
|
||||
inputs.file file("$rootDir/docs/manual/src/docbook/appendix-namespace.xml")
|
||||
}
|
||||
|
||||
integrationTest {
|
||||
systemProperties['apacheDSWorkDir'] = "${buildDir}/apacheDSWork"
|
||||
}
|
||||
}
|
||||
+20
-4
@@ -12,7 +12,10 @@
|
||||
*/
|
||||
package org.springframework.security.config.ldap;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
@@ -50,10 +53,11 @@ public class LdapServerBeanDefinitionParserTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useOfUrlAttributeCreatesCorrectContextSource() {
|
||||
public void useOfUrlAttributeCreatesCorrectContextSource() throws Exception {
|
||||
int port = getDefaultPort();
|
||||
// Create second "server" with a url pointing at embedded one
|
||||
appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif' port='33388'/>" +
|
||||
"<ldap-server ldif='classpath:test-server.ldif' id='blah' url='ldap://127.0.0.1:33388/dc=springframework,dc=org' />");
|
||||
appCtx = new InMemoryXmlApplicationContext("<ldap-server ldif='classpath:test-server.ldif' port='" + port + "'/>" +
|
||||
"<ldap-server ldif='classpath:test-server.ldif' id='blah' url='ldap://127.0.0.1:" + port + "/dc=springframework,dc=org' />");
|
||||
|
||||
// Check the default context source is still there.
|
||||
appCtx.getBean(BeanIds.CONTEXT_SOURCE);
|
||||
@@ -83,4 +87,16 @@ public class LdapServerBeanDefinitionParserTests {
|
||||
|
||||
assertEquals("classpath*:*.ldif", ReflectionTestUtils.getField(dsContainer, "ldifResources"));
|
||||
}
|
||||
|
||||
private int getDefaultPort() throws IOException {
|
||||
ServerSocket server = null;
|
||||
try {
|
||||
server = new ServerSocket(0);
|
||||
return server.getLocalPort();
|
||||
} finally {
|
||||
try {
|
||||
server.close();
|
||||
} catch(IOException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+31
-2
@@ -1,5 +1,8 @@
|
||||
package org.springframework.security.config.ldap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -40,7 +43,8 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
/** Defines the port the LDAP_PROVIDER server should run on */
|
||||
public static final String ATT_PORT = "port";
|
||||
public static final String OPT_DEFAULT_PORT = "33389";
|
||||
private static final int DEFAULT_PORT = 33389;
|
||||
public static final String OPT_DEFAULT_PORT = String.valueOf(DEFAULT_PORT);
|
||||
|
||||
|
||||
public BeanDefinition parse(Element elt, ParserContext parserContext) {
|
||||
@@ -101,7 +105,10 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
|
||||
String port = element.getAttribute(ATT_PORT);
|
||||
|
||||
if (!StringUtils.hasText(port)) {
|
||||
port = OPT_DEFAULT_PORT;
|
||||
port = getDefaultPort();
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("Using default port of " + port);
|
||||
}
|
||||
}
|
||||
|
||||
String url = "ldap://127.0.0.1:" + port + "/" + suffix;
|
||||
@@ -134,4 +141,26 @@ public class LdapServerBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
return (RootBeanDefinition) contextSource.getBeanDefinition();
|
||||
}
|
||||
|
||||
private String getDefaultPort() {
|
||||
ServerSocket serverSocket = null;
|
||||
try {
|
||||
try {
|
||||
serverSocket = new ServerSocket(DEFAULT_PORT);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
serverSocket = new ServerSocket(0);
|
||||
} catch(IOException e2) {
|
||||
return String.valueOf(DEFAULT_PORT);
|
||||
}
|
||||
}
|
||||
return String.valueOf(serverSocket.getLocalPort());
|
||||
} finally {
|
||||
if(serverSocket != null) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+19
-4
@@ -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,
|
||||
|
||||
+2
-2
@@ -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"
|
||||
+7
-3
@@ -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"/>
|
||||
|
||||
+19
-3
@@ -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
|
||||
|
||||
+17
@@ -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'
|
||||
|
||||
+50
@@ -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);
|
||||
}
|
||||
|
||||
+1
-2
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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 ========================================================================================================
|
||||
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=Access is denied
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=Empty Password
|
||||
AbstractSecurityInterceptor.authenticationNotFound=An Authentication object was not found in the SecurityContext
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Bad credentials
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=User credentials have expired
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=P\u0159\u00EDstup odep\u0159en
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=\u0160patn\u00E9 p\u0159ihla\u0161ovac\u00ED \u00FAdaje
|
||||
AbstractSecurityInterceptor.authenticationNotFound=Nebyl nalezen \u017E\u00E1dn\u00FD Authentication objekt v SecurityContext
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=\u0160patn\u00E9 p\u0159ihla\u0161ovac\u00ED \u00FAdaje
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Platnost u\u017Eivatelsk\u00E9ho hesla vypr\u0161ela
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
AbstractAccessDecisionManager.accessDenied=Zugriff verweigert
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=Ung\u00FCltige Anmeldedaten
|
||||
AbstractSecurityInterceptor.authenticationNotFound=Im SecurityContext wurde keine Authentifikation gefunden
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Ung\u00FCltige Benutzerberechtigungen
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Die G\u00FCltigkeit der Benutzerberechtigungen ist abgelaufen
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Ung\u00FCltige Anmeldedaten
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Die G\u00FCltigkeit der Anmeldedaten ist abgelaufen
|
||||
AbstractUserDetailsAuthenticationProvider.disabled=Der Benutzer ist deaktiviert
|
||||
AbstractUserDetailsAuthenticationProvider.expired=Die G\u00FCltigkeit des Benutzerkontos ist abgelaufen
|
||||
AbstractUserDetailsAuthenticationProvider.locked=Das Benutzerkonto ist gesperrt
|
||||
AbstractUserDetailsAuthenticationProvider.onlySupports=Nur UsernamePasswordAuthenticationToken wird unterst\u00FCtzt
|
||||
AccountStatusUserDetailsChecker.credentialsExpired=Die G\u00FCltigkeit der Benutzerberechtigungen ist abgelaufen
|
||||
AccountStatusUserDetailsChecker.credentialsExpired=Die G\u00FCltigkeit der Anmeldedaten ist abgelaufen
|
||||
AccountStatusUserDetailsChecker.disabled=Der Benutzer ist deaktiviert
|
||||
AccountStatusUserDetailsChecker.expired=Die G\u00FCltigkeit des Benutzerkontos ist abgelaufen
|
||||
AccountStatusUserDetailsChecker.locked=Das Benutzerkonto ist gesperrt
|
||||
AclEntryAfterInvocationProvider.noPermission=Authentifikation {0} hat KEINE Berechtigungen bez\u00FCglich des Dom\u00E4nen-Objekts {1}
|
||||
AnonymousAuthenticationProvider.incorrectKey=Das angegebene AnonymousAuthenticationToken enth\u00E4lt nicht den erwarteten Schl\u00FCssel
|
||||
BindAuthenticator.badCredentials=Ung\u00FCltige Benutzerberechtigungen
|
||||
BindAuthenticator.emptyPassword=Ung\u00FCltige Benutzerberechtigungen
|
||||
BindAuthenticator.badCredentials=Ung\u00FCltige Anmeldedaten
|
||||
BindAuthenticator.emptyPassword=Ung\u00FCltige Anmeldedaten
|
||||
CasAuthenticationProvider.incorrectKey=Das angegebene CasAuthenticationToken enth\u00E4lt nicht den erwarteten Schl\u00FCssel
|
||||
CasAuthenticationProvider.noServiceTicket=Es konnte kein CAS Service-Ticket zur Pr\u00FCfung geliefert werden
|
||||
ConcurrentSessionControlStrategy.exceededAllowed=Die maximale Sitzungs-Anzahl von {0} f\u00FCr diesen Nutzer wurde \u00FCberschritten
|
||||
@@ -29,14 +30,14 @@ DigestAuthenticationFilter.nonceNotTwoTokens=Nonce sollte zwei Elemente beinhalt
|
||||
DigestAuthenticationFilter.usernameNotFound=Benutzername {0} wurde nicht gefunden
|
||||
#JdbcDaoImpl.noAuthority=User {0} has no GrantedAuthority
|
||||
#JdbcDaoImpl.notFound=User {0} not found
|
||||
LdapAuthenticationProvider.badCredentials=Ung\u00FCltige Benutzerberechtigungen
|
||||
LdapAuthenticationProvider.credentialsExpired=Die G\u00FCltigkeit der Benutzerberechtigungen ist abgelaufen
|
||||
LdapAuthenticationProvider.badCredentials=Ung\u00FCltige Anmeldedaten
|
||||
LdapAuthenticationProvider.credentialsExpired=Die G\u00FCltigkeit der Anmeldedaten ist abgelaufen
|
||||
LdapAuthenticationProvider.disabled=Der Benutzer ist deaktiviert
|
||||
LdapAuthenticationProvider.expired=Die G\u00FCltigkeit des Benutzerkontos ist abgelaufen
|
||||
LdapAuthenticationProvider.locked=Das Benutzerkonto ist gesperrt
|
||||
LdapAuthenticationProvider.emptyUsername=Ein leerer Benutzername ist nicht erlaubt
|
||||
LdapAuthenticationProvider.onlySupports=Nur UsernamePasswordAuthenticationToken wird unterst\u00FCtzt
|
||||
PasswordComparisonAuthenticator.badCredentials=Ung\u00FCltige Benutzerberechtigungen
|
||||
PasswordComparisonAuthenticator.badCredentials=Ung\u00FCltige Anmeldedaten
|
||||
#PersistentTokenBasedRememberMeServices.cookieStolen=Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
|
||||
ProviderManager.providerNotFound=F\u00FCr {0} wurde kein AuthenticationProvider gefunden
|
||||
RememberMeAuthenticationProvider.incorrectKey=Das angegebene RememberMeAuthenticationToken enth\u00E4lt nicht den erwarteten Schl\u00FCssel
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=Acceso denegado
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=Credenciales err\u00F3neas
|
||||
AbstractSecurityInterceptor.authenticationNotFound=El objeto Authentication no ha sido encontrado en el SecurityContext
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Credenciales err\u00F3neas
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Las credenciales del usuario han expirado
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# Translation by Laurent Pireyn (laurent.pireyn@pisolutions.eu)
|
||||
# Translation by Valentin Crettaz (valentin.crettaz@consulthys.com)
|
||||
AbstractAccessDecisionManager.accessDenied=Acc\u00E8s refus\u00E9
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=Le mot de passe est obligatoire
|
||||
AbstractSecurityInterceptor.authenticationNotFound=Aucun objet Authentication n'a \u00E9t\u00E9 trouv\u00E9 dans le SecurityContext
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Les cr\u00E9ances sont erron\u00E9es
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Les cr\u00E9ances de l'utilisateur ont expir\u00E9
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=Accesso negato
|
||||
AbstractLdapAuthenticationProvider.badCredentials=Credenziali non valide
|
||||
AbstractSecurityInterceptor.authenticationNotFound=Nessuna autenticazione trovata dentro il Security Context
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Credenziali non valide
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Credenziali dell'utente scadute
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=\uC811\uADFC\uC774 \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
AbstractLdapAuthenticationProvider.badCredentials=\uBE44\uBC00\uBC88\uD638\uAC00 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
AbstractSecurityInterceptor.authenticationNotFound=SecurityContext\uC5D0\uC11C Authentication \uAC1D\uCCB4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=\uBE44\uBC00\uBC88\uD638(credential)\uAC00 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=\uBE44\uBC00\uBC88\uD638(credential)\uC758 \uC720\uD6A8 \uAE30\uAC04\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=Pri\u0117jimas neleid\u017eiamas
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=Tu\u0161\u010dias slapta\u017eodis
|
||||
AbstractSecurityInterceptor.authenticationNotFound=Authentication objektas nerastas SecurityContext kontekste
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Blogi kredencialai
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Pasibaig\u0117 vartotojo kredencial\u0173 galiojimas
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=Dost\u0119p zabroniony
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=Niepoprawne dane uwierzytelniaj\u0105ce
|
||||
AbstractSecurityInterceptor.authenticationNotFound=Obiekt Authentication nie zosta\u0142 odnaleziony w SecurityContext
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Niepoprawne dane uwierzytelniaj\u0105ce
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Wa\u017Cno\u015B\u0107 danych uwierzytelniaj\u0105cych wygas\u0142a
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Messages in Brazilian Portuguese
|
||||
# Translation by Leonardo Pinto (leoviveiros@gmail.com)
|
||||
AbstractAccessDecisionManager.accessDenied=Acesso negado
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=Usu\u00E1rio inexistente ou senha inv\u00E1lida
|
||||
AbstractSecurityInterceptor.authenticationNotFound=Um objeto de autentica\u00E7\u00E3o n\u00E3o foi encontrado no SecurityContext
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Usu\u00E1rio inexistente ou senha inv\u00E1lida
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Credenciais expiradas
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Spring Security Portuguese Resource Bundle
|
||||
# Author: José Santos
|
||||
AbstractAccessDecisionManager.accessDenied=Acesso negado
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=Credenciais inv\u00E1lidas
|
||||
AbstractSecurityInterceptor.authenticationNotFound=Objecto Authentication n\u00E3o encontrado em SecurityContext
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=Credenciais inv\u00E1lidas
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=As credenciais do utilizador expiraram
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=\u0414\u043E\u0441\u0442\u0443\u043F \u0437\u0430\u0431\u043E\u0440\u043E\u043D\u0435\u043D\u0438\u0439
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=\u0414\u0430\u043D\u0456 \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 \u043D\u0435\u043A\u043E\u0440\u0435\u043A\u0442\u043D\u0456
|
||||
AbstractSecurityInterceptor.authenticationNotFound=\u041E\u0431'\u0454\u043A\u0442 Authentication \u043D\u0435 \u0437\u043D\u0430\u0439\u0434\u0435\u043D\u0438\u0439 \u0432 SecurityContext
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=\u0414\u0430\u043D\u0456 \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 \u043D\u0435\u043A\u043E\u0440\u0435\u043A\u0442\u043D\u0456
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=\u041F\u043E\u0432\u043D\u043E\u0432\u0430\u0436\u0435\u043D\u043D\u044F \u043A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430 \u0432\u0438\u0447\u0435\u0440\u043F\u0430\u043B\u0438 \u0442\u0435\u0440\u043C\u0456\u043D \u0434\u0456\u0457
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
AbstractAccessDecisionManager.accessDenied=\u4E0D\u5141\u8BB8\u8BBF\u95EE
|
||||
AbstractLdapAuthenticationProvider.emptyPassword=\u574F\u7684\u51ED\u8BC1
|
||||
AbstractSecurityInterceptor.authenticationNotFound=\u672A\u5728SecurityContext\u4E2D\u67E5\u627E\u5230\u8BA4\u8BC1\u5BF9\u8C61
|
||||
AbstractUserDetailsAuthenticationProvider.badCredentials=\u574F\u7684\u51ED\u8BC1
|
||||
AbstractUserDetailsAuthenticationProvider.credentialsExpired=\u7528\u6237\u51ED\u8BC1\u5DF2\u8FC7\u671F
|
||||
|
||||
+10
-1
@@ -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><intercept-url></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">
|
||||
|
||||
@@ -526,7 +526,9 @@
|
||||
<property name="serviceProperties" ref="serviceProperties"/>
|
||||
<property name="authenticationDetailsSource">
|
||||
<bean class=
|
||||
"org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource"/>
|
||||
"org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource">
|
||||
<constructor-arg ref="serviceProperties"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
]]></programlisting></para>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -1 +1 @@
|
||||
version=3.1.4.CI-SNAPSHOT
|
||||
version=3.1.8.CI-SNAPSHOT
|
||||
|
||||
@@ -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'])
|
||||
|
||||
@@ -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
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+2
-2
@@ -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
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -33,13 +33,11 @@ integrationTest {
|
||||
include('**/ApacheDSServerIntegrationTests.class')
|
||||
// exclude('**/OpenLDAPIntegrationTestSuite.class')
|
||||
maxParallelForks = 1
|
||||
systemProperties['apacheDSWorkDir'] = "${buildDir}/apacheDSWork"
|
||||
}
|
||||
|
||||
// Runs a server for running the integration tests against (from an IDE, for example)
|
||||
task(ldapServer, dependsOn: 'integrationTestClasses', type: JavaExec) {
|
||||
classpath = sourceSets.integrationTest.runtimeClasspath
|
||||
main = 'org.springframework.security.ldap.ApacheDSServerIntegrationTests'
|
||||
systemProperties['apacheDSWorkDir'] = "${buildDir}/apacheDSWork"
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -25,7 +25,8 @@ public abstract class AbstractLdapIntegrationTests {
|
||||
|
||||
@BeforeClass
|
||||
public static void createContextSource() throws Exception {
|
||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/dc=springframework,dc=org");
|
||||
int serverPort = ApacheDSServerIntegrationTests.getServerPort();
|
||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:" + serverPort + "/dc=springframework,dc=org");
|
||||
// OpenLDAP configuration
|
||||
// contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:22389/dc=springsource,dc=com");
|
||||
// contextSource.setUserDn("cn=admin,dc=springsource,dc=com");
|
||||
|
||||
+28
-1
@@ -1,5 +1,8 @@
|
||||
package org.springframework.security.ldap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import org.junit.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
@@ -26,6 +29,7 @@ import org.springframework.security.ldap.userdetails.LdapUserDetailsManagerTests
|
||||
)
|
||||
public final class ApacheDSServerIntegrationTests {
|
||||
private static ApacheDSContainer server;
|
||||
private static Integer serverPort;
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws Exception {
|
||||
@@ -34,12 +38,15 @@ public final class ApacheDSServerIntegrationTests {
|
||||
// contextSource.setUserDn("cn=admin,dc=springsource,dc=com");
|
||||
// contextSource.setPassword("password");
|
||||
server = new ApacheDSContainer("dc=springframework,dc=org", "classpath:test-server.ldif");
|
||||
server.setPort(53389);
|
||||
int port = getAvailablePort();
|
||||
server.setPort(port);
|
||||
server.afterPropertiesSet();
|
||||
serverPort = port;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopServer() throws Exception {
|
||||
serverPort = null;
|
||||
if (server != null) {
|
||||
server.stop();
|
||||
}
|
||||
@@ -53,6 +60,12 @@ public final class ApacheDSServerIntegrationTests {
|
||||
server.afterPropertiesSet();
|
||||
}
|
||||
|
||||
public static int getServerPort() {
|
||||
if(serverPort == null) {
|
||||
throw new IllegalStateException("The ApacheDSContainer is not currently running");
|
||||
}
|
||||
return serverPort;
|
||||
}
|
||||
/*
|
||||
@After
|
||||
public final void reloadServerDataIfDirty() throws Exception {
|
||||
@@ -105,4 +118,18 @@ public final class ApacheDSServerIntegrationTests {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private static int getAvailablePort() throws IOException {
|
||||
ServerSocket serverSocket = null;
|
||||
try {
|
||||
serverSocket = new ServerSocket(0);
|
||||
return serverSocket.getLocalPort();
|
||||
} finally {
|
||||
if(serverSocket != null) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ public class DefaultSpringSecurityContextSourceTests extends AbstractLdapIntegra
|
||||
@Test
|
||||
public void serverUrlWithSpacesIsSupported() throws Exception {
|
||||
DefaultSpringSecurityContextSource
|
||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:53389/ou=space%20cadets,dc=springframework,dc=org");
|
||||
contextSource = new DefaultSpringSecurityContextSource("ldap://127.0.0.1:" + ApacheDSServerIntegrationTests.getServerPort() + "/ou=space%20cadets,dc=springframework,dc=org");
|
||||
contextSource.afterPropertiesSet();
|
||||
contextSource.getContext("uid=space cadet,ou=space cadets,dc=springframework,dc=org", "spacecadetspassword");
|
||||
}
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ public class SpringSecurityLdapTemplateTests extends AbstractLdapIntegrationTest
|
||||
public void nonSpringLdapSearchCodeTestMethod() throws Exception {
|
||||
java.util.Hashtable<String, String> env = new java.util.Hashtable<String, String>();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
env.put(Context.PROVIDER_URL, "ldap://localhost:53389");
|
||||
env.put(Context.PROVIDER_URL, "ldap://localhost:" + ApacheDSServerIntegrationTests.getServerPort());
|
||||
env.put(Context.SECURITY_PRINCIPAL, "");
|
||||
env.put(Context.SECURITY_CREDENTIALS, "");
|
||||
|
||||
|
||||
+53
-10
@@ -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) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-1
@@ -1,4 +1,18 @@
|
||||
package org.springframework.security.ldap.authentication;
|
||||
/*
|
||||
* Copyright 2002-2014 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.authentication;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -56,6 +70,11 @@ public abstract class AbstractLdapAuthenticationProvider implements Authenticati
|
||||
"Empty Username"));
|
||||
}
|
||||
|
||||
if (!StringUtils.hasLength(password)) {
|
||||
throw new BadCredentialsException(messages.getMessage("AbstractLdapAuthenticationProvider.emptyPassword",
|
||||
"Empty Password"));
|
||||
}
|
||||
|
||||
Assert.notNull(password, "Null password was supplied in authentication token");
|
||||
|
||||
DirContextOperations userData = doAuthentication(userToken);
|
||||
|
||||
@@ -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();
|
||||
|
||||
+7
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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
|
||||
@@ -141,6 +141,12 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
|
||||
provider.authenticate(joe);
|
||||
}
|
||||
|
||||
// SEC-2500
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
public void sec2500PreventAnonymousBind() {
|
||||
provider.authenticate(new UsernamePasswordAuthenticationToken("rwinch", ""));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected = IncorrectResultSizeDataAccessException.class)
|
||||
public void duplicateUserSearchCausesError() throws Exception {
|
||||
|
||||
@@ -34,7 +34,7 @@ dependencies {
|
||||
|
||||
compile project(':spring-security-core'),
|
||||
project(':spring-security-cas'),
|
||||
"org.jasig.cas.client:cas-client-core:3.1.12"
|
||||
"org.jasig.cas.client:cas-client-core:3.3.3"
|
||||
|
||||
runtime project(':spring-security-web'),
|
||||
project(':spring-security-config'),
|
||||
@@ -126,4 +126,4 @@ gradle.taskGraph.whenReady {graph ->
|
||||
|
||||
def casServer() {
|
||||
tasks.getByPath(':spring-security-samples-casserver:casServer')
|
||||
}
|
||||
}
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
<description>
|
||||
This is the main Spring configuration file with some of the main "core" classes defined. You shouldn't really
|
||||
modify this unless you
|
||||
know what you're doing!
|
||||
</description>
|
||||
|
||||
<!--
|
||||
Including this aspectj-autoproxy element will cause spring to automatically
|
||||
create proxies around any beans defined in this file that match the pointcuts
|
||||
of any aspects defined in this file.
|
||||
-->
|
||||
<aop:aspectj-autoproxy/>
|
||||
|
||||
<!--
|
||||
Declare the TimingAspect that we want to weave into the other beans
|
||||
defined in this config file.
|
||||
-->
|
||||
<bean id="timingAspect" class="org.perf4j.log4j.aop.TimingAspect"/>
|
||||
|
||||
|
||||
<!-- Message source for this context, loaded from localized "messages_xx" files -->
|
||||
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
|
||||
p:basename="messages"/>
|
||||
|
||||
<bean
|
||||
id="servicesManager"
|
||||
class="org.jasig.cas.services.DefaultServicesManagerImpl">
|
||||
<constructor-arg index="0" ref="serviceRegistryDao"/>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
Job to periodically reload services from service registry.
|
||||
This job is needed for a clustered CAS environment since service changes
|
||||
in one CAS node are not known to the other until a reload.
|
||||
-->
|
||||
<bean id="serviceRegistryReloaderJobDetail"
|
||||
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
|
||||
p:targetObject-ref="servicesManager"
|
||||
p:targetMethod="reload"/>
|
||||
|
||||
<bean id="periodicServiceRegistryReloaderTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"
|
||||
p:jobDetail-ref="serviceRegistryReloaderJobDetail"
|
||||
p:startDelay="120000"
|
||||
p:repeatInterval="120000"/>
|
||||
|
||||
<bean id="persistentIdGenerator"
|
||||
class="org.jasig.cas.authentication.principal.ShibbolethCompatiblePersistentIdGenerator"
|
||||
p:salt="casrocks"/>
|
||||
|
||||
<!-- CentralAuthenticationService -->
|
||||
<bean id="centralAuthenticationService" class="org.jasig.cas.CentralAuthenticationServiceImpl"
|
||||
p:ticketGrantingTicketExpirationPolicy-ref="grantingTicketExpirationPolicy"
|
||||
p:serviceTicketExpirationPolicy-ref="serviceTicketExpirationPolicy"
|
||||
p:authenticationManager-ref="authenticationManager"
|
||||
p:ticketGrantingTicketUniqueTicketIdGenerator-ref="ticketGrantingTicketUniqueIdGenerator"
|
||||
p:ticketRegistry-ref="ticketRegistry"
|
||||
p:servicesManager-ref="servicesManager"
|
||||
p:persistentIdGenerator-ref="persistentIdGenerator"
|
||||
p:uniqueTicketIdGeneratorsForService-ref="uniqueIdGeneratorsMap"/>
|
||||
|
||||
<bean id="proxy10Handler" class="org.jasig.cas.ticket.proxy.support.Cas10ProxyHandler"/>
|
||||
|
||||
<bean id="proxy20Handler" class="org.jasig.cas.ticket.proxy.support.Cas20ProxyHandler"
|
||||
p:httpClient-ref="httpClient"
|
||||
p:uniqueTicketIdGenerator-ref="proxy20TicketUniqueIdGenerator"/>
|
||||
|
||||
<!-- ADVISORS -->
|
||||
<bean id="advisorAutoProxyCreator"
|
||||
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
|
||||
|
||||
<bean id="validationAnnotationBeanPostProcessor" class="org.jasig.cas.util.CustomBeanValidationPostProcessor" />
|
||||
|
||||
<!-- The scheduler bean wires up any triggers that define scheduled tasks -->
|
||||
<bean id="scheduler" class="org.jasig.cas.util.AutowiringSchedulerFactoryBean"/>
|
||||
|
||||
<!-- Customizations -->
|
||||
|
||||
|
||||
<!-- Make requests synchronous. This ensures that Single Logout has completed before the Logout page renders. -->
|
||||
<bean id="httpClient" class="org.jasig.cas.util.HttpClient"
|
||||
p:readTimeout="5000"
|
||||
p:connectionTimeout="5000">
|
||||
<property name="executorService">
|
||||
<bean class="org.springframework.core.task.support.ExecutorServiceAdapter">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.core.task.SyncTaskExecutor"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
|
||||
<description>
|
||||
Customizations to the CAS Server. The name starts with zzz to ensure it is the last file loaded to override other bean definitions.
|
||||
</description>
|
||||
|
||||
<!-- Make requests synchronous. This ensures that Single Logout has completed before the Logout page renders. -->
|
||||
<bean id="httpClient" class="org.jasig.cas.util.HttpClient"
|
||||
p:readTimeout="5000"
|
||||
p:connectionTimeout="5000">
|
||||
<property name="executorService">
|
||||
<bean class="org.springframework.core.task.support.ExecutorServiceAdapter">
|
||||
<constructor-arg>
|
||||
<bean class="org.springframework.core.task.SyncTaskExecutor"/>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
||||
+1
-1
@@ -49,7 +49,7 @@ public class WebExpressionVoter implements AccessDecisionVoter<FilterInvocation>
|
||||
}
|
||||
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return clazz.isAssignableFrom(FilterInvocation.class);
|
||||
return FilterInvocation.class.isAssignableFrom(clazz);
|
||||
}
|
||||
|
||||
public void setExpressionHandler(SecurityExpressionHandler<FilterInvocation> expressionHandler) {
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+29
@@ -19,6 +19,10 @@ import org.springframework.security.web.FilterInvocation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
@@ -63,4 +67,29 @@ public class WebExpressionVoterTests {
|
||||
assertEquals(AccessDecisionVoter.ACCESS_DENIED, voter.vote(user, fi, attributes));
|
||||
}
|
||||
|
||||
// SEC-2507
|
||||
@Test
|
||||
public void supportFilterInvocationSubClass() {
|
||||
WebExpressionVoter voter = new WebExpressionVoter();
|
||||
assertTrue(voter.supports(FilterInvocationChild.class));
|
||||
}
|
||||
|
||||
private static class FilterInvocationChild extends FilterInvocation {
|
||||
public FilterInvocationChild(ServletRequest request,
|
||||
ServletResponse response, FilterChain chain) {
|
||||
super(request, response, chain);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportFilterInvocation() {
|
||||
WebExpressionVoter voter = new WebExpressionVoter();
|
||||
assertTrue(voter.supports(FilterInvocation.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsObjectIsFalse() {
|
||||
WebExpressionVoter voter = new WebExpressionVoter();
|
||||
assertFalse(voter.supports(Object.class));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
|
||||
+50
-2
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user