Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 114e00f1dd | |||
| a0e541eb70 | |||
| 477a5a7cd3 | |||
| 8918a7e693 | |||
| bf33f9acef | |||
| f1598b985c | |||
| cc1ab2c368 | |||
| aac4525737 | |||
| eeb099a04f | |||
| 3e90c7663f | |||
| cfec514082 | |||
| 80b123bf36 | |||
| ee6f9e0b92 | |||
| 2625de9c23 | |||
| a145653030 | |||
| 8bc0ef86da | |||
| a02d6ad2a4 | |||
| acdd9ba1db | |||
| e218ac2e40 | |||
| dd859c4a6e | |||
| 5d85a1c9d8 | |||
| 49167458d2 | |||
| 6b4edacde2 | |||
| b7cebee89e | |||
| 01787ea168 | |||
| e3e9758da7 | |||
| 46012d62af | |||
| 6eb8129173 |
Vendored
+5
-1
@@ -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
@@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+3
-1
@@ -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;
|
||||
}
|
||||
|
||||
+1
-11
@@ -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()) {
|
||||
|
||||
+19
-4
@@ -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.
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
+76
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
-8
@@ -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);
|
||||
|
||||
+20
-1
@@ -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
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
+3
-2
@@ -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> {
|
||||
|
||||
+11
@@ -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();
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
*/
|
||||
|
||||
+2
-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
|
||||
*/
|
||||
|
||||
+2
-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);
|
||||
}
|
||||
}
|
||||
|
||||
+59
@@ -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);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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>");
|
||||
|
||||
Reference in New Issue
Block a user