1
0
mirror of synced 2026-07-12 22:30:33 +00:00

Compare commits

...

28 Commits

Author SHA1 Message Date
Josh Cummings 114e00f1dd Release 5.1.3.RELEASE 2019-01-10 15:40:02 -07:00
Joe Grandja a0e541eb70 Update to Spring Boot 2.1.1.RELEASE
Fixes gh-6405
2019-01-10 14:55:31 -05:00
Joe Grandja 477a5a7cd3 Update to org.powermock 2.0.0
Fixes gh-6404
2019-01-10 14:52:57 -05:00
Joe Grandja 8918a7e693 Update to ehcache 2.10.6
Fixes gh-6403
2019-01-10 14:50:11 -05:00
Joe Grandja bf33f9acef Update to com.squareup.okhttp3 3.12.1
Fixes gh-6402
2019-01-10 14:48:30 -05:00
Joe Grandja f1598b985c Update to com.fasterxml.jackson.core 2.9.8
Fixes gh-6401
2019-01-10 14:44:56 -05:00
Joe Grandja cc1ab2c368 Update to cglib-nodep 3.2.10
Fixes gh-6400
2019-01-10 14:42:47 -05:00
Joe Grandja aac4525737 Update to spring-build-conventions:0.0.23.RELEASE
Fixes gh-6389
2019-01-10 12:28:48 -05:00
Joe Grandja eeb099a04f Update to Reactor Californium-SR4
Fixes gh-6387
2019-01-10 12:05:35 -05:00
Joe Grandja 3e90c7663f Update to Spring Framework 5.1.4
Fixes gh-6386
2019-01-10 12:03:24 -05:00
Joe Grandja cfec514082 Update to Spring Data Lovelace-SR4
Fixes gh-6385
2019-01-10 12:01:24 -05:00
Ankur Pathak 80b123bf36 fixes setting paramName only when it is not null
Fixes: gh-6223
2019-01-10 10:26:49 -06:00
Rafael Renan Pacheco ee6f9e0b92 cconfigured -> configured 2019-01-08 13:19:08 -06:00
Ankur Pathak 2625de9c23 Fixes typo in x,rnc files
1. Fixes type ammount to amount in *.rnc files
2. Regenerates *.xsd files from *.rnc files

Fixes: gh-6325
2019-01-08 11:33:46 -07:00
Onur Kagan Ozcan a145653030 Fix UsernamePasswordAuthenticationTokenDeserializer to handle customized object mapper inclusion settings
Resolves #4698
2019-01-07 14:23:53 -06:00
Slava Semushin 8bc0ef86da LazyCsrfTokenRepository: fix a typo in javadoc. 2019-01-07 13:36:17 -06:00
Joe Grandja a02d6ad2a4 AuthenticationFailureEvent should publish once
Fixes gh-6281
2018-12-21 07:55:24 -05:00
Josh Cummings acdd9ba1db Split Branches Into Multiple Sonarqube Projects
Eliminate analysis collisions and simplify application of analysis
quite periods.

Fixes: gh-6091
2018-12-18 14:42:45 -07:00
finke-ba e218ac2e40 Add conditionally servlet based support for spring security web jackson module. 2018-12-18 14:22:48 -06:00
Rob Winch dd859c4a6e Fix LoginPageGeneratingWebFilter Markup
Fixes: gh-6295
2018-12-17 11:18:40 -06:00
Ian He 5d85a1c9d8 Fix DefaultLoginPageGeneratingFilter Markup
the `</h3>` should be `</h2>`.
2018-12-17 10:50:23 -06:00
Zhanwei Wang 49167458d2 Improve error message for Chinese. 2018-12-06 11:59:35 -06:00
Robbie Martinus 6b4edacde2 SessionRegistryImpl uses computeIfAbsent
Fixes: gh-5834
2018-12-05 10:28:30 -06:00
lmagyar b7cebee89e SecurityContextCallableProcessingInterceptor thread visibility fix
Within class SecurityContextCallableProcessingInterceptor field securityContext should volatile.

Fixes gh-6143
2018-12-03 15:46:20 -06:00
Rafael Dominguez 01787ea168 Restored Jacoco default task dependence
This commit ensures that the jacoco plugin is applied when calling
check and test tasks.
Also remoed the clean task that prevented sonarqube using coverage data

Fixes: gh-6199
2018-11-30 14:26:36 -06:00
Rob Winch e3e9758da7 Fix Generics in ReactorContextTestExecutionListenerTests for JDK 9+
Issue: gh-6075
2018-11-30 12:08:50 -06:00
Aanuoluwapo Otitoola 46012d62af ReactorContextTestExecutionListener should use named hooks
Fixes: gh-6075
2018-11-30 11:16:47 -06:00
Rob Winch 6eb8129173 Next Snapshot 2018-11-28 08:45:53 -06:00
38 changed files with 297 additions and 112 deletions
Vendored
+5 -1
View File
@@ -30,7 +30,11 @@ try {
checkout scm
withCredentials([string(credentialsId: 'spring-sonar.login', variable: 'SONAR_LOGIN')]) {
try {
sh "./gradlew clean jacocoTestReport sonarqube -Dsonar.jacoco.reportPaths='**/build/jacoco/*.exec' -PexcludeProjects='**/samples/**' -Dsonar.host.url=$SPRING_SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN --refresh-dependencies --no-daemon --stacktrace"
if ("master" == env.BRANCH_NAME) {
sh "./gradlew sonarqube -PexcludeProjects='**/samples/**' -Dsonar.host.url=$SPRING_SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN --refresh-dependencies --no-daemon --stacktrace"
} else {
sh "./gradlew sonarqube -PexcludeProjects='**/samples/**' -Dsonar.projectKey='spring-security-${env.BRANCH_NAME}' -Dsonar.projectName='spring-security-${env.BRANCH_NAME}' -Dsonar.host.url=$SPRING_SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN --refresh-dependencies --no-daemon --stacktrace"
}
} catch(Exception e) {
currentBuild.result = 'FAILED: sonar'
throw e
+1 -16
View File
@@ -1,6 +1,6 @@
buildscript {
dependencies {
classpath 'io.spring.gradle:spring-build-conventions:0.0.22.RELEASE'
classpath 'io.spring.gradle:spring-build-conventions:0.0.23.RELEASE'
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
}
repositories {
@@ -19,23 +19,8 @@ ext.milestoneBuild = !(snapshotBuild || releaseBuild)
dependencyManagementExport.projects = subprojects.findAll { !it.name.contains('-boot') }
// Disable JaCoCo when not explicitly requested to enable caching of test
// See https://discuss.gradle.org/t/do-not-cache-if-condition-matched-jacoco-agent-configured-with-append-true-satisfied/23504
gradle.taskGraph.whenReady { graph ->
def enabled = graph.allTasks.any { it instanceof JacocoReport }
subprojects { project ->
project.plugins.withType(JacocoPlugin) {
project.tasks.withType(Test) {
jacoco.enabled = enabled
}
}
}
}
subprojects {
plugins.withType(JavaPlugin) {
project.sourceCompatibility='1.8'
}
}
@@ -739,7 +739,7 @@ hsts-options.attlist &=
## Specifies if subdomains should be included. Default true.
attribute include-subdomains {xsd:boolean}?
hsts-options.attlist &=
## Specifies the maximum ammount of time the host should be considered a Known HSTS Host. Default one year.
## Specifies the maximum amount of time the host should be considered a Known HSTS Host. Default one year.
attribute max-age-seconds {xsd:integer}?
hsts-options.attlist &=
## The RequestMatcher instance to be used to determine if the header should be set. Default is if HttpServletRequest.isSecure() is true.
@@ -2299,7 +2299,7 @@
</xs:attribute>
<xs:attribute name="max-age-seconds" type="xs:integer">
<xs:annotation>
<xs:documentation>Specifies the maximum ammount of time the host should be considered a Known HSTS Host.
<xs:documentation>Specifies the maximum amount of time the host should be considered a Known HSTS Host.
Default one year.
</xs:documentation>
</xs:annotation>
@@ -759,7 +759,7 @@ hsts-options.attlist &=
## Specifies if subdomains should be included. Default true.
attribute include-subdomains {xsd:boolean}?
hsts-options.attlist &=
## Specifies the maximum ammount of time the host should be considered a Known HSTS Host. Default one year.
## Specifies the maximum amount of time the host should be considered a Known HSTS Host. Default one year.
attribute max-age-seconds {xsd:integer}?
hsts-options.attlist &=
## The RequestMatcher instance to be used to determine if the header should be set. Default is if HttpServletRequest.isSecure() is true.
@@ -2358,7 +2358,7 @@
</xs:attribute>
<xs:attribute name="max-age-seconds" type="xs:integer">
<xs:annotation>
<xs:documentation>Specifies the maximum ammount of time the host should be considered a Known HSTS Host.
<xs:documentation>Specifies the maximum amount of time the host should be considered a Known HSTS Host.
Default one year.
</xs:documentation>
</xs:annotation>
@@ -768,7 +768,7 @@ hsts-options.attlist &=
## Specifies if subdomains should be included. Default true.
attribute include-subdomains {xsd:boolean}?
hsts-options.attlist &=
## Specifies the maximum ammount of time the host should be considered a Known HSTS Host. Default one year.
## Specifies the maximum amount of time the host should be considered a Known HSTS Host. Default one year.
attribute max-age-seconds {xsd:integer}?
hsts-options.attlist &=
## The RequestMatcher instance to be used to determine if the header should be set. Default is if HttpServletRequest.isSecure() is true.
@@ -2387,7 +2387,7 @@
</xs:attribute>
<xs:attribute name="max-age-seconds" type="xs:integer">
<xs:annotation>
<xs:documentation>Specifies the maximum ammount of time the host should be considered a Known HSTS Host.
<xs:documentation>Specifies the maximum amount of time the host should be considered a Known HSTS Host.
Default one year.
</xs:documentation>
</xs:annotation>
@@ -770,7 +770,7 @@ hsts-options.attlist &=
## Specifies if subdomains should be included. Default true.
attribute include-subdomains {xsd:boolean}?
hsts-options.attlist &=
## Specifies the maximum ammount of time the host should be considered a Known HSTS Host. Default one year.
## Specifies the maximum amount of time the host should be considered a Known HSTS Host. Default one year.
attribute max-age-seconds {xsd:integer}?
hsts-options.attlist &=
## The RequestMatcher instance to be used to determine if the header should be set. Default is if HttpServletRequest.isSecure() is true.
@@ -2402,7 +2402,7 @@
</xs:attribute>
<xs:attribute name="max-age-seconds" type="xs:integer">
<xs:annotation>
<xs:documentation>Specifies the maximum ammount of time the host should be considered a Known HSTS Host.
<xs:documentation>Specifies the maximum amount of time the host should be considered a Known HSTS Host.
Default one year.
</xs:documentation>
</xs:annotation>
@@ -760,7 +760,7 @@ hsts-options.attlist &=
## Specifies if subdomains should be included. Default true.
attribute include-subdomains {xsd:boolean}?
hsts-options.attlist &=
## Specifies the maximum ammount of time the host should be considered a Known HSTS Host. Default one year.
## Specifies the maximum amount of time the host should be considered a Known HSTS Host. Default one year.
attribute max-age-seconds {xsd:integer}?
hsts-options.attlist &=
## The RequestMatcher instance to be used to determine if the header should be set. Default is if HttpServletRequest.isSecure() is true.
@@ -2297,7 +2297,7 @@
</xs:attribute>
<xs:attribute name="max-age-seconds" type="xs:integer">
<xs:annotation>
<xs:documentation>Specifies the maximum ammount of time the host should be considered a Known HSTS Host.
<xs:documentation>Specifies the maximum amount of time the host should be considered a Known HSTS Host.
Default one year.
</xs:documentation>
</xs:annotation>
@@ -760,7 +760,7 @@ hsts-options.attlist &=
## Specifies if subdomains should be included. Default true.
attribute include-subdomains {xsd:boolean}?
hsts-options.attlist &=
## Specifies the maximum ammount of time the host should be considered a Known HSTS Host. Default one year.
## Specifies the maximum amount of time the host should be considered a Known HSTS Host. Default one year.
attribute max-age-seconds {xsd:integer}?
hsts-options.attlist &=
## The RequestMatcher instance to be used to determine if the header should be set. Default is if HttpServletRequest.isSecure() is true.
@@ -2298,7 +2298,7 @@
</xs:attribute>
<xs:attribute name="max-age-seconds" type="xs:integer">
<xs:annotation>
<xs:documentation>Specifies the maximum ammount of time the host should be considered a Known HSTS Host.
<xs:documentation>Specifies the maximum amount of time the host should be considered a Known HSTS Host.
Default one year.
</xs:documentation>
</xs:annotation>
@@ -112,7 +112,9 @@ class MethodSecurityEvaluationContext extends StandardEvaluationContext {
}
for (int i = 0; i < args.length; i++) {
super.setVariable(paramNames[i], args[i]);
if (paramNames[i] != null) {
setVariable(paramNames[i], args[i]);
}
}
}
@@ -156,6 +156,7 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
throws AuthenticationException {
Class<? extends Authentication> toTest = authentication.getClass();
AuthenticationException lastException = null;
AuthenticationException parentException = null;
Authentication result = null;
Authentication parentResult = null;
boolean debug = logger.isDebugEnabled();
@@ -205,7 +206,7 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
// handled the request
}
catch (AuthenticationException e) {
lastException = e;
lastException = parentException = e;
}
}
@@ -234,7 +235,11 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
"No AuthenticationProvider found for {0}"));
}
prepareException(lastException, authentication);
// If the parent AuthenticationManager was attempted and failed than it will publish an AbstractAuthenticationFailureEvent
// This check prevents a duplicate AbstractAuthenticationFailureEvent if the parent AuthenticationManager already published it
if (parentException == null) {
prepareException(lastException, authentication);
}
throw lastException;
}
@@ -132,17 +132,7 @@ public class SessionRegistryImpl implements SessionRegistry,
sessionIds.put(sessionId,
new SessionInformation(principal, sessionId, new Date()));
Set<String> sessionsUsedByPrincipal = principals.get(principal);
if (sessionsUsedByPrincipal == null) {
sessionsUsedByPrincipal = new CopyOnWriteArraySet<>();
Set<String> prevSessionsUsedByPrincipal = principals.putIfAbsent(principal,
sessionsUsedByPrincipal);
if (prevSessionsUsedByPrincipal != null) {
sessionsUsedByPrincipal = prevSessionsUsedByPrincipal;
}
}
Set<String> sessionsUsedByPrincipal = principals.computeIfAbsent(principal, key -> new CopyOnWriteArraySet<>());
sessionsUsedByPrincipal.add(sessionId);
if (logger.isTraceEnabled()) {
@@ -57,6 +57,7 @@ import java.util.Set;
* mapper.registerModule(new CoreJackson2Module());
* mapper.registerModule(new CasJackson2Module());
* mapper.registerModule(new WebJackson2Module());
* mapper.registerModule(new WebServletJackson2Module());
* </pre>
*
* @author Jitendra Singh.
@@ -70,6 +71,8 @@ public final class SecurityJackson2Modules {
"org.springframework.security.cas.jackson2.CasJackson2Module",
"org.springframework.security.web.jackson2.WebJackson2Module"
);
private static final String webServletJackson2ModuleClass =
"org.springframework.security.web.jackson2.WebServletJackson2Module";
private SecurityJackson2Modules() {
}
@@ -109,14 +112,26 @@ public final class SecurityJackson2Modules {
public static List<Module> getModules(ClassLoader loader) {
List<Module> modules = new ArrayList<>();
for (String className : securityJackson2ModuleClasses) {
Module module = loadAndGetInstance(className, loader);
if (module != null) {
modules.add(module);
}
addToModulesList(loader, modules, className);
}
if (ClassUtils.isPresent("javax.servlet.http.Cookie", loader)) {
addToModulesList(loader, modules, webServletJackson2ModuleClass);
}
return modules;
}
/**
* @param loader the ClassLoader to use
* @param modules list of the modules to add
* @param className name of the class to instantiate
*/
private static void addToModulesList(ClassLoader loader, List<Module> modules, String className) {
Module module = loadAndGetInstance(className, loader);
if (module != null) {
modules.add(module);
}
}
/**
* Creates a TypeResolverBuilder that performs whitelisting.
* @return a TypeResolverBuilder that performs whitelisting.
@@ -41,6 +41,7 @@ import org.springframework.security.core.GrantedAuthority;
*
* @author Jitendra Singh
* @author Greg Turnquist
* @author Onur Kagan Ozcan
* @see UsernamePasswordAuthenticationTokenMixin
* @since 4.2
*/
@@ -69,7 +70,7 @@ class UsernamePasswordAuthenticationTokenDeserializer extends JsonDeserializer<U
}
JsonNode credentialsNode = readJsonNode(jsonNode, "credentials");
Object credentials;
if (credentialsNode.isNull()) {
if (credentialsNode.isNull() || credentialsNode.isMissingNode()) {
credentials = null;
} else {
credentials = credentialsNode.asText();
@@ -83,7 +84,7 @@ class UsernamePasswordAuthenticationTokenDeserializer extends JsonDeserializer<U
token = new UsernamePasswordAuthenticationToken(principal, credentials);
}
JsonNode detailsNode = readJsonNode(jsonNode, "details");
if (detailsNode.isNull()) {
if (detailsNode.isNull() || detailsNode.isMissingNode()) {
token.setDetails(null);
} else {
token.setDetails(detailsNode);
@@ -1,7 +1,7 @@
AbstractAccessDecisionManager.accessDenied=\u4E0D\u5141\u8BB8\u8BBF\u95EE
AbstractLdapAuthenticationProvider.emptyPassword=\u574F\u7684\u51ED\u8BC1
AbstractLdapAuthenticationProvider.emptyPassword=\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
AbstractSecurityInterceptor.authenticationNotFound=\u672A\u5728SecurityContext\u4E2D\u67E5\u627E\u5230\u8BA4\u8BC1\u5BF9\u8C61
AbstractUserDetailsAuthenticationProvider.badCredentials=\u574F\u7684\u51ED\u8BC1
AbstractUserDetailsAuthenticationProvider.badCredentials=\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
AbstractUserDetailsAuthenticationProvider.credentialsExpired=\u7528\u6237\u51ED\u8BC1\u5DF2\u8FC7\u671F
AbstractUserDetailsAuthenticationProvider.disabled=\u7528\u6237\u5DF2\u5931\u6548
AbstractUserDetailsAuthenticationProvider.expired=\u7528\u6237\u5E10\u53F7\u5DF2\u8FC7\u671F
@@ -13,8 +13,8 @@ AccountStatusUserDetailsChecker.expired=\u7528\u6237\u5E10\u53F7\u5DF2\u8FC7\u67
AccountStatusUserDetailsChecker.locked=\u7528\u6237\u5E10\u53F7\u5DF2\u88AB\u9501\u5B9A
AclEntryAfterInvocationProvider.noPermission=\u7ED9\u5B9A\u7684Authentication\u5BF9\u8C61({0})\u6839\u672C\u65E0\u6743\u64CD\u63A7\u9886\u57DF\u5BF9\u8C61({1})
AnonymousAuthenticationProvider.incorrectKey=\u5C55\u793A\u7684AnonymousAuthenticationToken\u4E0D\u542B\u6709\u9884\u671F\u7684key
BindAuthenticator.badCredentials=\u574F\u7684\u51ED\u8BC1
BindAuthenticator.emptyPassword=\u574F\u7684\u51ED\u8BC1
BindAuthenticator.badCredentials=\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
BindAuthenticator.emptyPassword=\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
CasAuthenticationProvider.incorrectKey=\u5C55\u793A\u7684CasAuthenticationToken\u4E0D\u542B\u6709\u9884\u671F\u7684key
CasAuthenticationProvider.noServiceTicket=\u672A\u80FD\u591F\u6B63\u786E\u63D0\u4F9B\u5F85\u9A8C\u8BC1\u7684CAS\u670D\u52A1\u7968\u6839
ConcurrentSessionControlAuthenticationStrategy.exceededAllowed=\u5DF2\u7ECF\u8D85\u8FC7\u4E86\u5F53\u524D\u4E3B\u4F53({0})\u88AB\u5141\u8BB8\u7684\u6700\u5927\u4F1A\u8BDD\u6570\u91CF
@@ -30,14 +30,14 @@ DigestAuthenticationFilter.nonceNotTwoTokens=Nonce\u5E94\u8BE5\u7531\u4E24\u90E8
DigestAuthenticationFilter.usernameNotFound=\u7528\u6237\u540D{0}\u672A\u627E\u5230
JdbcDaoImpl.noAuthority=\u6CA1\u6709\u4E3A\u7528\u6237{0}\u6307\u5B9A\u89D2\u8272
JdbcDaoImpl.notFound=\u672A\u627E\u5230\u7528\u6237{0}
LdapAuthenticationProvider.badCredentials=\u574F\u7684\u51ED\u8BC1
LdapAuthenticationProvider.badCredentials=\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
LdapAuthenticationProvider.credentialsExpired=\u7528\u6237\u51ED\u8BC1\u5DF2\u8FC7\u671F
LdapAuthenticationProvider.disabled=\u7528\u6237\u5DF2\u5931\u6548
LdapAuthenticationProvider.expired=\u7528\u6237\u5E10\u53F7\u5DF2\u8FC7\u671F
LdapAuthenticationProvider.locked=\u7528\u6237\u5E10\u53F7\u5DF2\u88AB\u9501\u5B9A
LdapAuthenticationProvider.emptyUsername=\u7528\u6237\u540D\u4E0D\u5141\u8BB8\u4E3A\u7A7A
LdapAuthenticationProvider.onlySupports=\u4EC5\u4EC5\u652F\u6301UsernamePasswordAuthenticationToken
PasswordComparisonAuthenticator.badCredentials=\u574F\u7684\u51ED\u8BC1
PasswordComparisonAuthenticator.badCredentials=\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef
#PersistentTokenBasedRememberMeServices.cookieStolen=Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack.
ProviderManager.providerNotFound=\u672A\u67E5\u627E\u5230\u9488\u5BF9{0}\u7684AuthenticationProvider
RememberMeAuthenticationProvider.incorrectKey=\u5C55\u793ARememberMeAuthenticationToken\u4E0D\u542B\u6709\u9884\u671F\u7684key
@@ -0,0 +1,76 @@
/*
* Copyright 2002-2016 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.access.expression.method;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.lang.Nullable;
import org.springframework.security.core.Authentication;
import org.springframework.util.ReflectionUtils;
import static org.mockito.Mockito.doReturn;
/**
* @author shabarijonnalagadda
*
*/
@RunWith(MockitoJUnitRunner.class)
public class MethodSecurityEvaluationContextTests {
@Mock
private ParameterNameDiscoverer paramNameDiscoverer;
@Mock
private Authentication authentication;
@Mock
private MethodInvocation methodInvocation;
@Test
public void lookupVariableWhenParameterNameNullThenNotSet() {
Class<String> type = String.class;
Method method = ReflectionUtils.findMethod(String.class, "contains", CharSequence.class);
doReturn(new String[] {null}).when(paramNameDiscoverer).getParameterNames(method);
doReturn(new Object[]{null}).when(methodInvocation).getArguments();
doReturn(type).when(methodInvocation).getThis();
doReturn(method).when(methodInvocation).getMethod();
NotNullVariableMethodSecurityEvaluationContext context= new NotNullVariableMethodSecurityEvaluationContext(authentication, methodInvocation, paramNameDiscoverer);
context.lookupVariable("testVariable");
}
private static class NotNullVariableMethodSecurityEvaluationContext
extends MethodSecurityEvaluationContext {
public NotNullVariableMethodSecurityEvaluationContext(Authentication auth, MethodInvocation mi,
ParameterNameDiscoverer parameterNameDiscoverer) {
super(auth, mi, parameterNameDiscoverer);
}
@Override
public void setVariable(String name, @Nullable Object value) {
if ( name == null ) {
throw new IllegalArgumentException("name should not be null");
}
else {
super.setVariable(name, value);
}
}
}
}
@@ -16,18 +16,20 @@
package org.springframework.security.authentication;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.springframework.context.MessageSource;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.Mockito.*;
/**
* Tests {@link ProviderManager}.
*
@@ -257,7 +259,6 @@ public class ProviderManagerTests {
catch (BadCredentialsException e) {
assertThat(e).isSameAs(expected);
}
verify(publisher).publishAuthenticationFailure(expected, authReq);
}
@Test
@@ -298,6 +299,32 @@ public class ProviderManagerTests {
}
}
// gh-6281
@Test
public void authenticateWhenFailsInParentAndPublishesThenChildDoesNotPublish() {
BadCredentialsException badCredentialsExParent = new BadCredentialsException("Bad Credentials in parent");
ProviderManager parentMgr = new ProviderManager(
Collections.singletonList(createProviderWhichThrows(badCredentialsExParent)));
ProviderManager childMgr = new ProviderManager(Collections.singletonList(createProviderWhichThrows(
new BadCredentialsException("Bad Credentials in child"))), parentMgr);
AuthenticationEventPublisher publisher = mock(AuthenticationEventPublisher.class);
parentMgr.setAuthenticationEventPublisher(publisher);
childMgr.setAuthenticationEventPublisher(publisher);
final Authentication authReq = mock(Authentication.class);
try {
childMgr.authenticate(authReq);
fail("Expected exception");
}
catch (BadCredentialsException e) {
assertThat(e).isSameAs(badCredentialsExParent);
}
verify(publisher).publishAuthenticationFailure(badCredentialsExParent, authReq); // Parent publishes
verifyNoMoreInteractions(publisher); // Child should not publish (duplicate event)
}
private AuthenticationProvider createProviderWhichThrows(
final AuthenticationException e) {
AuthenticationProvider provider = mock(AuthenticationProvider.class);
@@ -29,11 +29,16 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import static org.assertj.core.api.Assertions.*;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.ALWAYS;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_ABSENT;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
import static com.fasterxml.jackson.annotation.JsonInclude.Value.construct;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Jitendra Singh
* @author Greg Turnquist
* @author Onur Kagan Ozcan
* @since 4.2
*/
public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixinTests {
@@ -163,6 +168,20 @@ public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixin
assertThat(deserialized).isEqualTo(original);
}
@Test
public void serializingThenDeserializingWithConfiguredObjectMapperShouldWork() throws IOException {
// given
this.mapper.setDefaultPropertyInclusion(construct(ALWAYS, NON_NULL)).setSerializationInclusion(NON_ABSENT);
UsernamePasswordAuthenticationToken original = new UsernamePasswordAuthenticationToken("Frodo", null);
// when
String serialized = this.mapper.writeValueAsString(original);
UsernamePasswordAuthenticationToken deserialized =
this.mapper.readValue(serialized, UsernamePasswordAuthenticationToken.class);
// then
assertThat(deserialized).isEqualTo(original);
}
private UsernamePasswordAuthenticationToken createToken() {
User user = createDefaultUser();
@@ -183,7 +183,7 @@ A typical configuration might look like this:
----
Here we have four roles in a hierarchy `ROLE_ADMIN => ROLE_STAFF => ROLE_USER => ROLE_GUEST`.
A user who is authenticated with `ROLE_ADMIN`, will behave as if they have all four roles when security constraints are evaluated against an `AccessDecisionManager` cconfigured with the above `RoleHierarchyVoter`.
A user who is authenticated with `ROLE_ADMIN`, will behave as if they have all four roles when security constraints are evaluated against an `AccessDecisionManager` configured with the above `RoleHierarchyVoter`.
The `>` symbol can be thought of as meaning "includes".
Role hierarchies offer a convenient means of simplifying the access-control configuration data for your application and/or reducing the number of authorities which you need to assign to a user.
+2 -2
View File
@@ -1,3 +1,3 @@
gaeVersion=1.9.68
springBootVersion=2.1.0.RELEASE
version=5.1.2.RELEASE
springBootVersion=2.1.1.RELEASE
version=5.1.3.RELEASE
+16 -16
View File
@@ -1,13 +1,13 @@
if (!project.hasProperty('reactorVersion')) {
ext.reactorVersion = 'Californium-SR3'
ext.reactorVersion = 'Californium-SR4'
}
if (!project.hasProperty('springVersion')) {
ext.springVersion = '5.1.3.RELEASE'
ext.springVersion = '5.1.4.RELEASE'
}
if (!project.hasProperty('springDataVersion')) {
ext.springDataVersion = 'Lovelace-SR3'
ext.springDataVersion = 'Lovelace-SR4'
}
dependencyManagement {
@@ -17,17 +17,17 @@ dependencyManagement {
mavenBom "org.springframework.data:spring-data-releasetrain:${springDataVersion}"
}
dependencies {
dependency 'cglib:cglib-nodep:3.2.9'
dependency 'com.squareup.okhttp3:mockwebserver:3.12.0'
dependency 'cglib:cglib-nodep:3.2.10'
dependency 'com.squareup.okhttp3:mockwebserver:3.12.1'
dependency 'opensymphony:sitemesh:2.4.2'
dependency 'org.gebish:geb-spock:0.10.0'
dependency 'org.jasig.cas:cas-server-webapp:4.2.7'
dependency 'org.powermock:powermock-api-mockito2:2.0.0-RC.4'
dependency 'org.powermock:powermock-api-support:2.0.0-RC.4'
dependency 'org.powermock:powermock-core:2.0.0-RC.4'
dependency 'org.powermock:powermock-module-junit4-common:2.0.0-RC.4'
dependency 'org.powermock:powermock-module-junit4:2.0.0-RC.4'
dependency 'org.powermock:powermock-reflect:2.0.0-RC.4'
dependency 'org.powermock:powermock-api-mockito2:2.0.0'
dependency 'org.powermock:powermock-api-support:2.0.0'
dependency 'org.powermock:powermock-core:2.0.0'
dependency 'org.powermock:powermock-module-junit4-common:2.0.0'
dependency 'org.powermock:powermock-module-junit4:2.0.0'
dependency 'org.powermock:powermock-reflect:2.0.0'
dependency 'org.python:jython:2.5.0'
dependency 'org.spockframework:spock-core:1.0-groovy-2.4'
dependency 'org.spockframework:spock-spring:1.0-groovy-2.4'
@@ -40,9 +40,9 @@ dependencyManagement {
dependency 'asm:asm:3.1'
dependency 'ch.qos.logback:logback-classic:1.2.3'
dependency 'ch.qos.logback:logback-core:1.2.3'
dependency 'com.fasterxml.jackson.core:jackson-annotations:2.9.7'
dependency 'com.fasterxml.jackson.core:jackson-core:2.9.7'
dependency 'com.fasterxml.jackson.core:jackson-databind:2.9.7'
dependency 'com.fasterxml.jackson.core:jackson-annotations:2.9.8'
dependency 'com.fasterxml.jackson.core:jackson-core:2.9.8'
dependency 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
dependency 'com.fasterxml:classmate:1.3.4'
dependency 'com.github.stephenc.jcip:jcip-annotations:1.0-1'
dependency 'com.google.appengine:appengine-api-1.0-sdk:1.9.64'
@@ -56,7 +56,7 @@ dependencyManagement {
dependency 'com.nimbusds:lang-tag:1.4.3'
dependency 'com.nimbusds:nimbus-jose-jwt:6.0.2'
dependency 'com.nimbusds:oauth2-oidc-sdk:6.0'
dependency 'com.squareup.okhttp3:okhttp:3.12.0'
dependency 'com.squareup.okhttp3:okhttp:3.12.1'
dependency 'com.squareup.okio:okio:1.13.0'
dependency 'com.sun.xml.bind:jaxb-core:2.3.0.1'
dependency 'com.sun.xml.bind:jaxb-impl:2.3.0.1'
@@ -86,7 +86,7 @@ dependencyManagement {
dependency 'net.jcip:jcip-annotations:1.0'
dependency 'net.minidev:accessors-smart:1.2'
dependency 'net.minidev:json-smart:2.3'
dependency 'net.sf.ehcache:ehcache:2.10.5'
dependency 'net.sf.ehcache:ehcache:2.10.6'
dependency 'net.sourceforge.htmlunit:htmlunit:2.33'
dependency 'net.sourceforge.htmlunit:neko-htmlunit:2.32'
dependency 'net.sourceforge.nekohtml:nekohtml:1.9.22'
@@ -44,6 +44,7 @@ public class ReactorContextTestExecutionListener
extends DelegatingTestExecutionListener {
private static final String HOOKS_CLASS_NAME = "reactor.core.publisher.Hooks";
private static final String CONTEXT_OPERATOR_KEY = SecurityContext.class.getName();
public ReactorContextTestExecutionListener() {
super(createDelegate());
@@ -59,12 +60,12 @@ public class ReactorContextTestExecutionListener
@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
SecurityContext securityContext = TestSecurityContextHolder.getContext();
Hooks.onLastOperator(Operators.lift((s, sub) -> new SecuritySubContext<>(sub, securityContext)));
Hooks.onLastOperator(CONTEXT_OPERATOR_KEY, Operators.lift((s, sub) -> new SecuritySubContext<>(sub, securityContext)));
}
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
Hooks.resetOnLastOperator();
Hooks.resetOnLastOperator(CONTEXT_OPERATOR_KEY);
}
private static class SecuritySubContext<T> implements CoreSubscriber<T> {
@@ -174,6 +174,17 @@ public class ReactorContextTestExecutionListenerTests {
assertThat(Mono.subscriberContext().block().isEmpty()).isTrue();
}
@Test
public void afterTestMethodWhenDifferentHookIsRegistered() throws Exception {
Object obj = new Object();
Hooks.onLastOperator("CUSTOM_HOOK", p -> Mono.just(obj));
this.listener.afterTestMethod(this.testContext);
Object result = Mono.subscriberContext().block();
assertThat(result).isEqualTo(obj);
}
@Test
public void orderWhenComparedToWithSecurityContextTestExecutionListenerIsAfter() {
OrderComparator comparator = new OrderComparator();
@@ -272,7 +272,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
}
if (oauth2LoginEnabled) {
sb.append("<h2 class=\"form-signin-heading\">Login with OAuth 2.0</h3>");
sb.append("<h2 class=\"form-signin-heading\">Login with OAuth 2.0</h2>");
sb.append(createError(loginError, errorMsg));
sb.append(createLogoutSuccess(logoutSuccess));
sb.append("<table class=\"table table-striped\">\n");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@@ -41,7 +41,7 @@ import org.springframework.web.context.request.async.CallableProcessingIntercept
*/
public final class SecurityContextCallableProcessingInterceptor extends
CallableProcessingInterceptorAdapter {
private SecurityContext securityContext;
private volatile SecurityContext securityContext;
/**
* Create a new {@link SecurityContextCallableProcessingInterceptor} that uses the
@@ -60,7 +60,7 @@ public final class LazyCsrfTokenRepository implements CsrfTokenRepository {
/**
* Does nothing if the {@link CsrfToken} is not null. Saving is done only when the
* {@link CsrfToken#getToken()} iis accessed from
* {@link CsrfToken#getToken()} is accessed from
* {@link #generateToken(HttpServletRequest)}. If it is null, then the save is
* performed immediately.
*/
@@ -25,11 +25,11 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
*
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new WebJackson2Module());
* mapper.registerModule(new WebServletJackson2Module());
* </pre>
*
* @author Jitendra Singh
* @see WebJackson2Module
* @see WebServletJackson2Module
* @see org.springframework.security.jackson2.SecurityJackson2Modules
* @since 4.2
*/
@@ -29,11 +29,11 @@ import org.springframework.security.web.savedrequest.DefaultSavedRequest;
* <p>
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new WebJackson2Module());
* mapper.registerModule(new WebServletJackson2Module());
* </pre>
*
* @author Jitendra Singh
* @see WebJackson2Module
* @see WebServletJackson2Module
* @see org.springframework.security.jackson2.SecurityJackson2Modules
* @since 4.2
*/
@@ -24,11 +24,11 @@ import com.fasterxml.jackson.annotation.*;
*
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new WebJackson2Module());
* mapper.registerModule(new WebServletJackson2Module());
* </pre>
*
* @author Jitendra Singh.
* @see WebJackson2Module
* @see WebServletJackson2Module
* @see org.springframework.security.jackson2.SecurityJackson2Modules
* @since 4.2
*/
@@ -23,11 +23,11 @@ import com.fasterxml.jackson.annotation.*;
*
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new WebJackson2Module());
* mapper.registerModule(new WebServletJackson2Module());
* </pre>
*
* @author Jitendra Singh
* @see WebJackson2Module
* @see WebServletJackson2Module
* @see org.springframework.security.jackson2.SecurityJackson2Modules
* @since 4.2
*/
@@ -16,23 +16,17 @@
package org.springframework.security.web.jackson2;
import javax.servlet.http.Cookie;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.security.web.csrf.DefaultCsrfToken;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.savedrequest.SavedCookie;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
/**
* Jackson module for spring-security-web. This module register {@link CookieMixin},
* {@link DefaultCsrfTokenMixin}, {@link DefaultSavedRequestMixin} and {@link WebAuthenticationDetailsMixin}. If no
* default typing enabled by default then it'll enable it because typing info is needed to properly serialize/deserialize objects.
* Jackson module for spring-security-web. This module register {@link DefaultCsrfTokenMixin} and
* {@link PreAuthenticatedAuthenticationTokenMixin}. If no default typing enabled by default then it'll enable
* it because typing info is needed to properly serialize/deserialize objects.
* In order to use this module just add this module into your ObjectMapper configuration.
*
* <pre>
@@ -53,12 +47,8 @@ public class WebJackson2Module extends SimpleModule {
@Override
public void setupModule(SetupContext context) {
SecurityJackson2Modules.enableDefaultTyping((ObjectMapper) context.getOwner());
context.setMixInAnnotations(Cookie.class, CookieMixin.class);
context.setMixInAnnotations(SavedCookie.class, SavedCookieMixin.class);
SecurityJackson2Modules.enableDefaultTyping(context.getOwner());
context.setMixInAnnotations(DefaultCsrfToken.class, DefaultCsrfTokenMixin.class);
context.setMixInAnnotations(DefaultSavedRequest.class, DefaultSavedRequestMixin.class);
context.setMixInAnnotations(WebAuthenticationDetails.class, WebAuthenticationDetailsMixin.class);
context.setMixInAnnotations(PreAuthenticatedAuthenticationToken.class, PreAuthenticatedAuthenticationTokenMixin.class);
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2015-2016 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.jackson2;
import javax.servlet.http.Cookie;
import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.savedrequest.SavedCookie;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.module.SimpleModule;
/**
* Jackson module for spring-security-web related to servlet. This module register {@link CookieMixin},
* {@link SavedCookieMixin}, {@link DefaultSavedRequestMixin} and {@link WebAuthenticationDetailsMixin}. If no
* default typing enabled by default then it'll enable it because typing info is needed to properly serialize/deserialize objects.
* In order to use this module just add this module into your ObjectMapper configuration.
*
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new WebServletJackson2Module());
* </pre>
* <b>Note: use {@link SecurityJackson2Modules#getModules(ClassLoader)} to get list of all security modules.</b>
*
* @author Boris Finkelshteyn
* @see SecurityJackson2Modules
* @since 5.1
*/
public class WebServletJackson2Module extends SimpleModule {
public WebServletJackson2Module() {
super(WebJackson2Module.class.getName(), new Version(1, 0, 0, null, null, null));
}
@Override
public void setupModule(SetupContext context) {
SecurityJackson2Modules.enableDefaultTyping(context.getOwner());
context.setMixInAnnotations(Cookie.class, CookieMixin.class);
context.setMixInAnnotations(SavedCookie.class, SavedCookieMixin.class);
context.setMixInAnnotations(DefaultSavedRequest.class, DefaultSavedRequestMixin.class);
context.setMixInAnnotations(WebAuthenticationDetails.class, WebAuthenticationDetailsMixin.class);
}
}
@@ -140,7 +140,7 @@ public class LoginPageGeneratingWebFilter implements WebFilter {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append("<div class=\"container\"><h2 class=\"form-signin-heading\">Login with OAuth 2.0</h3>");
sb.append("<div class=\"container\"><h2 class=\"form-signin-heading\">Login with OAuth 2.0</h2>");
sb.append("<table class=\"table table-striped\">\n");
for (Map.Entry<String, String> clientAuthenticationUrlToClientName : oauth2AuthenticationUrlToClientName.entrySet()) {
sb.append(" <tr><td>");