Compare commits

..

No commits in common. "main" and "7.1.0-M2" have entirely different histories.

307 changed files with 1341 additions and 9085 deletions

View File

@ -64,7 +64,6 @@ updates:
- shibboleth
ignore:
- dependency-name: com.nimbusds:nimbus-jose-jwt
- dependency-name: io.spring.nullability:*
- dependency-name: org.python:jython
- dependency-name: org.apache.directory.server:*
- dependency-name: org.apache.directory.shared:*

View File

@ -14,7 +14,7 @@ permissions:
jobs:
snapshot-test:
name: Test Against Snapshots
uses: spring-io/spring-security-release-tools/.github/workflows/test.yml@729fed56d42122f88583aff1be35c0800b7d77e9 # v1.0.14
uses: spring-io/spring-security-release-tools/.github/workflows/test.yml@7d42d82298553f123a9dad622e0eac725aaf52ef # v1.0.13
strategy:
matrix:
include:

View File

@ -55,7 +55,7 @@ jobs:
release-repo-url: https://repo1.maven.org/maven2
artifact-path: org/springframework/security/spring-security-core
slack-announcing-id: spring-security-announcing
java-version: 25
java-version: 25:q
secrets: inherit
send-notification:
name: Send Notification

View File

@ -9,7 +9,6 @@ permissions:
jobs:
upgrade_wrapper:
name: Execution
if: ${{ github.repository == 'spring-projects/spring-security' }}
runs-on: ubuntu-latest
steps:
- name: Set up Git configuration

View File

@ -34,7 +34,7 @@ jobs:
run: ./gradlew -PbuildSrc.skipTests=true :spring-security-docs:antora
- name: Upload Docs
id: upload
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: docs
path: docs/build/site

View File

@ -12,9 +12,8 @@ permissions:
jobs:
update-antora-ui-spring:
name: Update on Supported Branches
if: ${{ github.repository == 'spring-projects/spring-security' }}
runs-on: ubuntu-latest
name: Update on Supported Branches
strategy:
matrix:
branch: [ '6.5.x', '7.0.x', 'main' ]
@ -26,9 +25,8 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
antora-file-path: 'docs/antora-playbook.yml'
update-antora-ui-spring-docs-build:
name: Update on docs-build
if: ${{ github.repository == 'spring-projects/spring-security' }}
runs-on: ubuntu-latest
name: Update on docs-build
steps:
- uses: spring-io/spring-doc-actions/update-antora-spring-ui@415e2b11a766ba64799fffb5c97a4f7e17f677cf
name: Update

View File

@ -68,27 +68,6 @@ The https://github.com/spring-projects/spring-security/tree/docs-build[playbook
Discover more commands with `./gradlew tasks`.
=== IDE setup (IntelliJ)
No special steps are needed to open Spring Security in IntelliJ.
=== IDE setup (Eclipse and VS Code)
To work in Eclipse or VS Code, first generate Eclipse metadata so you can import the project into Eclipse or VS Code:
[indent=0]
----
./gradlew cleanEclipse eclipse
----
If you have not built the project yet, run `./gradlew publishToMavenLocal` first so dependencies are resolved.
*VS Code:* Open the repository root as a folder. The repository includes `.vscode/settings.json` which disables automatic Gradle import so that the generated Eclipse metadata (`.classpath`, `.project`) is used. Do not use the Gradle for Java extension to import the project.
*Eclipse:* File → Import → General → Existing Projects into Workspace, then select the repository root.
The build uses a custom Eclipse plugin to work around Gradle dependency cycles that confuse IDE metadata generation. You may see Eclipse warnings about `xml-apis` from some test dependencies; those are excluded in the build and can be ignored.
== Getting Support
Check out the https://stackoverflow.com/questions/tagged/spring-security[Spring Security tags on Stack Overflow].
https://spring.io/support[Commercial support] is available too.

View File

@ -31,7 +31,6 @@ import org.jspecify.annotations.Nullable;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.method.AbstractFallbackMethodSecurityMetadataSource;
import org.springframework.util.StringUtils;
/**
* Sources method security metadata from major JSR 250 security annotations.
@ -109,7 +108,7 @@ public class Jsr250MethodSecurityMetadataSource extends AbstractFallbackMethodSe
if (role == null) {
return role;
}
if (!StringUtils.hasLength(this.defaultRolePrefix)) {
if (this.defaultRolePrefix == null || this.defaultRolePrefix.length() == 0) {
return role;
}
if (role.startsWith(this.defaultRolePrefix)) {

View File

@ -23,7 +23,6 @@ import java.util.Locale;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.core.log.LogMessage;
import org.springframework.security.access.PermissionEvaluator;
@ -74,7 +73,7 @@ public class AclPermissionEvaluator implements PermissionEvaluator {
* be overridden using a null check in the expression itself).
*/
@Override
public boolean hasPermission(Authentication authentication, @Nullable Object domainObject, Object permission) {
public boolean hasPermission(Authentication authentication, Object domainObject, Object permission) {
if (domainObject == null) {
return false;
}

View File

@ -1,79 +0,0 @@
/*
* Copyright 2004-present 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
*
* https://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.acls.aot.hint;
import java.util.stream.Stream;
import org.jspecify.annotations.Nullable;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.security.acls.domain.AclImpl;
import org.springframework.security.acls.domain.AuditLogger;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.GrantedAuthoritySid;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.AccessControlEntry;
import org.springframework.security.acls.model.Acl;
import org.springframework.security.acls.model.AuditableAccessControlEntry;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Sid;
/**
* {@link RuntimeHintsRegistrar} for ACL (Access Control List) classes.
*
* @author Josh Long
*/
class AclRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
registerAclDomainHints(hints);
registerJdbcSchemaHints(hints);
}
private void registerAclDomainHints(RuntimeHints hints) {
// Register core ACL domain types
Stream
.of(Acl.class, AccessControlEntry.class, AuditableAccessControlEntry.class, ObjectIdentity.class, Sid.class,
AclImpl.class, AccessControlEntry.class, AuditLogger.class, ObjectIdentityImpl.class,
PrincipalSid.class, GrantedAuthoritySid.class, BasePermission.class)
.forEach((c) -> hints.reflection()
.registerType(TypeReference.of(c),
(builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.ACCESS_DECLARED_FIELDS)));
}
private void registerJdbcSchemaHints(RuntimeHints hints) {
String[] sqlFiles = new String[] { "createAclSchema.sql", "createAclSchemaMySQL.sql",
"createAclSchemaOracle.sql", "createAclSchemaPostgres.sql", "createAclSchemaSqlServer.sql",
"createAclSchemaWithAclClassIdType.sql", "select.sql" };
for (String sqlFile : sqlFiles) {
Resource sqlResource = new ClassPathResource(sqlFile);
if (sqlResource.exists()) {
hints.resources().registerResource(sqlResource);
}
}
}
}

View File

@ -1,23 +0,0 @@
/*
* Copyright 2004-present 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
*
* https://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.
*/
/**
* AOT and native image hint support for ACLs.
*/
@NullMarked
package org.springframework.security.acls.aot.hint;
import org.jspecify.annotations.NullMarked;

View File

@ -1,2 +0,0 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.security.acls.aot.hint.AclRuntimeHints

View File

@ -1,6 +1,5 @@
apply plugin: 'io.spring.convention.spring-module'
apply plugin: 'io.freefair.aspectj'
apply plugin: 'javadoc-warnings-error'
apply plugin: 'compile-warnings-error'
compileAspectj {

View File

@ -8,4 +8,3 @@ tasks.withType(JavaCompile) {
tasks.withType(KotlinCompile) {
kotlinOptions.allWarningsAsErrors = true
}

View File

@ -34,7 +34,6 @@ import org.springframework.util.Assert;
* and using the current URL minus the artifact and the corresponding value.
*
* @author Rob Winch
* @author Ngoc Nhan
*/
final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
implements ServiceAuthenticationDetails {
@ -75,9 +74,10 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
if (this == obj) {
return true;
}
if (!super.equals(obj) || !(obj instanceof DefaultServiceAuthenticationDetails that)) {
if (!super.equals(obj) || !(obj instanceof DefaultServiceAuthenticationDetails)) {
return false;
}
ServiceAuthenticationDetails that = (ServiceAuthenticationDetails) obj;
return this.serviceUrl.equals(that.getServiceUrl());
}
@ -101,11 +101,7 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
/**
* If present, removes the artifactParameterName and the corresponding value from the
* query String.
* @param request the current {@link HttpServletRequest} to obtain the
* {@link #getServiceUrl()} from.
* @param artifactPattern the {@link Pattern} that will be used to clean up the query
* string from containing the artifact name and value. This can be created using
* {@link #createArtifactPattern(String)}.
* @param request
* @return the query String minus the artifactParameterName and the corresponding
* value.
*/
@ -115,7 +111,7 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
return null;
}
String result = artifactPattern.matcher(query).replaceFirst("");
if (result.isEmpty()) {
if (result.length() == 0) {
return null;
}
// strip off the trailing & only if the artifact was the first query param
@ -126,9 +122,8 @@ final class DefaultServiceAuthenticationDetails extends WebAuthenticationDetails
* Creates a {@link Pattern} that can be passed into the constructor. This allows the
* {@link Pattern} to be reused for every instance of
* {@link DefaultServiceAuthenticationDetails}.
* @param artifactParameterName the artifactParameterName that is removed from the
* current URL. The result becomes the service url. Cannot be null or an empty String.
* @return a {@link Pattern}
* @param artifactParameterName
* @return
*/
static Pattern createArtifactPattern(String artifactParameterName) {
Assert.hasLength(artifactParameterName, "artifactParameterName is expected to have a length");

View File

@ -5,7 +5,6 @@ apply plugin: 'io.spring.convention.spring-module'
apply plugin: 'trang'
apply plugin: 'security-kotlin'
apply plugin: 'test-compile-target-jdk25'
apply plugin: 'compile-warnings-error'
apply plugin: 'javadoc-warnings-error'
configurations {

View File

@ -1,126 +0,0 @@
package org.springframework.security.config.ldap;
import javax.naming.Name;
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.core.support.BaseLdapPathAware;
import org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor;
import org.springframework.ldap.core.support.BaseLdapPathContextSource;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
import org.springframework.security.ldap.server.UnboundIdContainer;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringTestContextExtension.class)
public class Ldap247ITests {
public final SpringTestContext spring = new SpringTestContext(this);
@Autowired
private LdapGroupDao ldapGroupDao;
@Test
public void verifyThatBasePathIsProperlyPopulated() {
this.spring.register(FromContextSourceConfig.class).autowire();
assertThat(this.ldapGroupDao).isNotNull();
assertThat(this.ldapGroupDao.getBasePath()).isNotNull();
}
@Configuration
@EnableMethodSecurity
@Import(BaseLdapServerConfig.class)
static class FromContextSourceConfig {
@Bean
AuthenticationManager authenticationManager(BaseLdapPathContextSource contextSource) {
LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
factory.setUserDnPatterns("uid={0},ou=people");
return factory.createAuthenticationManager();
}
@Bean
static MethodSecurityExpressionHandler securityExpressionHandler(LdapGroupDao ldap) {
return new MethodSecurityExpressionHandler(ldap);
}
@Bean
static LdapGroupDao ldapGroupDao() {
return new LdapGroupDao();
}
@Bean
static BaseLdapPathBeanPostProcessor baseLdapPathBeanPostProcessor() {
return new BaseLdapPathBeanPostProcessor();
}
}
@Configuration
@EnableWebSecurity
static class BaseLdapServerConfig implements DisposableBean {
private UnboundIdContainer container;
@Bean
UnboundIdContainer ldapServer() {
this.container = new UnboundIdContainer("dc=springframework,dc=org", "classpath:/test-server.ldif");
this.container.setPort(0);
return this.container;
}
@Bean
BaseLdapPathContextSource contextSource(UnboundIdContainer container) {
int port = container.getPort();
return new DefaultSpringSecurityContextSource("ldap://localhost:" + port + "/dc=springframework,dc=org");
}
@Override
public void destroy() {
this.container.stop();
}
}
static class MethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
private final LdapGroupDao groupDao;
MethodSecurityExpressionHandler(LdapGroupDao groupDao) {
this.groupDao = groupDao;
}
}
static class LdapGroupDao implements BaseLdapPathAware {
private Name basePath;
LdapGroupDao() {
super();
}
@Override
public void setBaseLdapPath(DistinguishedName baseLdapPath) {
this.basePath = baseLdapPath;
}
public Name getBasePath() {
return this.basePath;
}
}
}

View File

@ -36,7 +36,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.log.LogMessage;
import org.springframework.lang.Contract;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
@ -303,7 +302,6 @@ public class AuthenticationConfiguration {
}
@Override
@Contract("!null -> !null; null -> null")
public String encode(CharSequence rawPassword) {
return getPasswordEncoder().encode(rawPassword);
}

View File

@ -30,7 +30,6 @@ import org.springframework.context.annotation.Scope;
import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.lang.Contract;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
@ -294,7 +293,6 @@ class HttpSecurityConfiguration {
}
@Override
@Contract("!null -> !null; null -> null")
public String encode(CharSequence rawPassword) {
return getPasswordEncoder().encode(rawPassword);
}

View File

@ -40,11 +40,11 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
import org.springframework.security.oauth2.server.authorization.web.OAuth2DeviceVerificationEndpointFilter;
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2DeviceAuthorizationConsentAuthenticationConverter;
import org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2DeviceVerificationAuthenticationConverter;
import org.springframework.security.web.access.intercept.AuthorizationFilter;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.DelegatingAuthenticationConverter;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
@ -279,7 +279,8 @@ public final class OAuth2DeviceVerificationEndpointConfigurer extends AbstractOA
if (StringUtils.hasText(this.consentPage)) {
deviceVerificationEndpointFilter.setConsentPage(this.consentPage);
}
builder.addFilterAfter(postProcess(deviceVerificationEndpointFilter), AuthorizationFilter.class);
builder.addFilterBefore(postProcess(deviceVerificationEndpointFilter),
AbstractPreAuthenticatedProcessingFilter.class);
}
@Override

View File

@ -521,10 +521,8 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
public OpaqueTokenConfigurer introspectionUri(String introspectionUri) {
Assert.notNull(introspectionUri, "introspectionUri cannot be null");
this.introspectionUri = introspectionUri;
this.introspector = () -> SpringOpaqueTokenIntrospector.withIntrospectionUri(this.introspectionUri)
.clientId(this.clientId)
.clientSecret(this.clientSecret)
.build();
this.introspector = () -> new SpringOpaqueTokenIntrospector(this.introspectionUri, this.clientId,
this.clientSecret);
return this;
}
@ -533,10 +531,8 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
Assert.notNull(clientSecret, "clientSecret cannot be null");
this.clientId = clientId;
this.clientSecret = clientSecret;
this.introspector = () -> SpringOpaqueTokenIntrospector.withIntrospectionUri(this.introspectionUri)
.clientId(this.clientId)
.clientSecret(this.clientSecret)
.build();
this.introspector = () -> new SpringOpaqueTokenIntrospector(this.introspectionUri, this.clientId,
this.clientSecret);
return this;
}

View File

@ -255,9 +255,7 @@ class ServerHttpSecurityConfiguration {
if (this.passwordEncoder != null) {
manager.setPasswordEncoder(this.passwordEncoder);
}
if (this.userDetailsPasswordService != null) {
manager.setUserDetailsPasswordService(this.userDetailsPasswordService);
}
manager.setUserDetailsPasswordService(this.userDetailsPasswordService);
manager.setCompromisedPasswordChecker(this.compromisedPasswordChecker);
return this.postProcessor.postProcess(manager);
}

View File

@ -124,10 +124,6 @@ class AuthorizationFilterParser implements BeanDefinitionParser {
List<Element> interceptMessages = DomUtils.getChildElementsByTagName(element, Elements.INTERCEPT_URL);
for (Element interceptMessage : interceptMessages) {
String accessExpression = interceptMessage.getAttribute(ATT_ACCESS);
if (!StringUtils.hasText(accessExpression)) {
parserContext.getReaderContext().error("access attribute cannot be empty or null", interceptMessage);
continue;
}
BeanDefinitionBuilder authorizationManager = BeanDefinitionBuilder
.rootBeanDefinition(WebExpressionAuthorizationManager.class);
authorizationManager.addPropertyReference("expressionHandler", expressionHandlerRef);

View File

@ -142,11 +142,10 @@ public class FilterInvocationSecurityMetadataSourceParser implements BeanDefinit
ManagedMap<BeanMetadataElement, BeanDefinition> filterInvocationDefinitionMap = new ManagedMap<>();
for (Element urlElt : urlElts) {
String access = urlElt.getAttribute(ATT_ACCESS);
String path = urlElt.getAttribute(ATT_PATTERN);
if (!StringUtils.hasText(access)) {
parserContext.getReaderContext().error("access attribute cannot be empty or null", urlElt);
continue;
}
String path = urlElt.getAttribute(ATT_PATTERN);
String matcherRef = urlElt.getAttribute(HttpSecurityBeanDefinitionParser.ATT_REQUEST_MATCHER_REF);
boolean hasMatcherRef = StringUtils.hasText(matcherRef);
if (!hasMatcherRef && !StringUtils.hasText(path)) {

View File

@ -23,7 +23,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import org.jspecify.annotations.Nullable;
import org.w3c.dom.Element;
import org.springframework.beans.BeansException;
@ -42,18 +44,25 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.beans.factory.xml.XmlReaderContext;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.messaging.Message;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler;
import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.access.vote.ConsensusBased;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.authorization.AuthorizationResult;
import org.springframework.security.config.Elements;
import org.springframework.security.config.http.MessageMatcherFactoryBean;
import org.springframework.security.config.web.messaging.PathPatternMessageMatcherBuilderFactoryBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.messaging.access.expression.ExpressionBasedMessageSecurityMetadataSourceFactory;
import org.springframework.security.messaging.access.expression.MessageExpressionAuthorizationManager;
import org.springframework.security.messaging.access.expression.MessageAuthorizationContextSecurityExpressionHandler;
import org.springframework.security.messaging.access.expression.MessageExpressionVoter;
import org.springframework.security.messaging.access.intercept.AuthorizationChannelInterceptor;
import org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor;
@ -66,6 +75,7 @@ import org.springframework.security.messaging.util.matcher.SimpMessageTypeMatche
import org.springframework.security.messaging.web.csrf.XorCsrfChannelInterceptor;
import org.springframework.security.messaging.web.socket.server.CsrfTokenHandshakeInterceptor;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
@ -209,15 +219,9 @@ public final class WebSocketMessageBrokerSecurityBeanDefinitionParser implements
String messageType = interceptMessage.getAttribute(TYPE_ATTR);
BeanDefinition matcher = createMatcher(matcherPattern, messageType, parserContext, interceptMessage);
BeanDefinitionBuilder authorizationManager = BeanDefinitionBuilder
.rootBeanDefinition(MessageExpressionAuthorizationManager.class);
.rootBeanDefinition(ExpressionBasedAuthorizationManager.class);
if (StringUtils.hasText(expressionHandlerRef)) {
BeanDefinitionBuilder authorizationManagerBuilder = BeanDefinitionBuilder
.rootBeanDefinition(MessageExpressionAuthorizationManager.class);
authorizationManagerBuilder.setFactoryMethod("withSecurityExpressionHandler");
authorizationManagerBuilder.addConstructorArgReference(expressionHandlerRef);
String authorizationManagerBuilderRef = context
.registerWithGeneratedName(authorizationManagerBuilder.getBeanDefinition());
authorizationManager.setFactoryMethodOnBean("expression", authorizationManagerBuilderRef);
authorizationManager.addConstructorArgReference(expressionHandlerRef);
}
authorizationManager.addConstructorArgValue(accessExpression);
matcherToExpression.put(matcher, authorizationManager.getBeanDefinition());
@ -435,6 +439,35 @@ public final class WebSocketMessageBrokerSecurityBeanDefinitionParser implements
}
private static final class ExpressionBasedAuthorizationManager
implements AuthorizationManager<MessageAuthorizationContext<?>> {
private final SecurityExpressionHandler<MessageAuthorizationContext<?>> expressionHandler;
private final Expression expression;
private ExpressionBasedAuthorizationManager(String expression) {
this(new MessageAuthorizationContextSecurityExpressionHandler(), expression);
}
private ExpressionBasedAuthorizationManager(
SecurityExpressionHandler<MessageAuthorizationContext<?>> expressionHandler, String expression) {
Assert.notNull(expressionHandler, "expressionHandler cannot be null");
Assert.notNull(expression, "expression cannot be null");
this.expressionHandler = expressionHandler;
this.expression = this.expressionHandler.getExpressionParser().parseExpression(expression);
}
@Override
public AuthorizationResult authorize(Supplier<? extends @Nullable Authentication> authentication,
MessageAuthorizationContext<?> object) {
EvaluationContext context = this.expressionHandler.createEvaluationContext(authentication, object);
boolean granted = ExpressionUtils.evaluateAsBoolean(this.expression, context);
return new AuthorizationDecision(granted);
}
}
private static class MessageMatcherDelegatingAuthorizationManagerFactory {
private static AuthorizationManager<Message<?>> createMessageMatcherDelegatingAuthorizationManager(

View File

@ -286,7 +286,7 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
if (factoryOfRequestAuthorizationContext != null) {
return factoryOfRequestAuthorizationContext
}
val factoryOfObjectType = ResolvableType.forClassWithGenerics(AuthorizationManagerFactory::class.java, Any::class.java)
val factoryOfObjectType = ResolvableType.forClassWithGenerics(AuthorizationManagerFactory::class.java, Object::class.java)
val factoryOfAny = context.getBeanProvider<AuthorizationManagerFactory<Any>>(factoryOfObjectType).getIfUnique()
if (factoryOfAny != null) {
return factoryOfAny
@ -303,20 +303,20 @@ class AuthorizeHttpRequestsDsl : AbstractRequestMatcherDsl {
return defaultFactory
}
private fun resolveRolePrefix(context: ApplicationContext): String? {
private fun resolveRolePrefix(context: ApplicationContext): String {
val beanNames = context.getBeanNamesForType(GrantedAuthorityDefaults::class.java)
if (beanNames.isNotEmpty()) {
return context.getBean(GrantedAuthorityDefaults::class.java).rolePrefix
}
return null
return "ROLE_";
}
private fun resolveRoleHierarchy(context: ApplicationContext): RoleHierarchy? {
private fun resolveRoleHierarchy(context: ApplicationContext): RoleHierarchy {
val beanNames = context.getBeanNamesForType(RoleHierarchy::class.java)
if (beanNames.isNotEmpty()) {
return context.getBean(RoleHierarchy::class.java)
}
return null
return NullRoleHierarchy()
}
}

View File

@ -37,11 +37,9 @@ class HeadersDsl {
private var cacheControl: ((HeadersConfigurer<HttpSecurity>.CacheControlConfig) -> Unit)? = null
private var hsts: ((HeadersConfigurer<HttpSecurity>.HstsConfig) -> Unit)? = null
private var frameOptions: ((HeadersConfigurer<HttpSecurity>.FrameOptionsConfig) -> Unit)? = null
@Suppress("DEPRECATION")
private var hpkp: ((HeadersConfigurer<HttpSecurity>.HpkpConfig) -> Unit)? = null
private var contentSecurityPolicy: ((HeadersConfigurer<HttpSecurity>.ContentSecurityPolicyConfig) -> Unit)? = null
private var referrerPolicy: ((HeadersConfigurer<HttpSecurity>.ReferrerPolicyConfig) -> Unit)? = null
@Suppress("DEPRECATION")
private var featurePolicyDirectives: String? = null
private var permissionsPolicy: ((HeadersConfigurer<HttpSecurity>.PermissionsPolicyConfig) -> Unit)? = null
private var crossOriginOpenerPolicy: ((HeadersConfigurer<HttpSecurity>.CrossOriginOpenerPolicyConfig) -> Unit)? = null
@ -122,7 +120,6 @@ class HeadersDsl {
* @deprecated see <a href="https://owasp.org/www-community/controls/Certificate_and_Public_Key_Pinning">Certificate and Public Key Pinning</a> for more context
*/
@Deprecated(message = "as of 5.8 with no replacement")
@Suppress("DEPRECATION")
fun httpPublicKeyPinning(hpkpConfig: HttpPublicKeyPinningDsl.() -> Unit) {
this.hpkp = HttpPublicKeyPinningDsl().apply(hpkpConfig).get()
}
@ -170,7 +167,6 @@ class HeadersDsl {
* @param policyDirectives policyDirectives the security policy directive(s)
*/
@Deprecated("Use 'permissionsPolicy { }' instead.")
@Suppress("DEPRECATION")
fun featurePolicy(policyDirectives: String) {
this.featurePolicyDirectives = policyDirectives
}

View File

@ -614,7 +614,6 @@ class HttpSecurityDsl(private val http: HttpSecurity, private val init: HttpSecu
* @see [RequiresChannelDsl]
* @deprecated please use [redirectToHttps] instead
*/
@Suppress("DEPRECATION")
@Deprecated(message="since 6.5 use redirectToHttps instead")
fun requiresChannel(requiresChannelConfiguration: RequiresChannelDsl.() -> Unit) {
val requiresChannelCustomizer = RequiresChannelDsl().apply(requiresChannelConfiguration).get()

View File

@ -14,8 +14,6 @@
* limitations under the License.
*/
@file:Suppress("DEPRECATION")
package org.springframework.security.config.annotation.web
import org.springframework.security.config.annotation.web.builders.HttpSecurity

View File

@ -62,7 +62,6 @@ class X509Dsl {
authenticationDetailsSource?.also { x509.authenticationDetailsSource(authenticationDetailsSource) }
userDetailsService?.also { x509.userDetailsService(userDetailsService) }
authenticationUserDetailsService?.also { x509.authenticationUserDetailsService(authenticationUserDetailsService) }
@Suppress("DEPRECATION")
subjectPrincipalRegex?.also { x509.subjectPrincipalRegex(subjectPrincipalRegex) }
}
}

View File

@ -14,8 +14,6 @@
* limitations under the License.
*/
@file:Suppress("DEPRECATION")
package org.springframework.security.config.annotation.web.headers
import org.springframework.security.config.annotation.web.builders.HttpSecurity

View File

@ -68,11 +68,12 @@ class SessionFixationDsl {
internal fun get(): (SessionManagementConfigurer<HttpSecurity>.SessionFixationConfigurer) -> Unit {
return { sessionFixation ->
strategy?.also {
when (it) {
when (strategy) {
SessionFixationStrategy.NEW -> sessionFixation.newSession()
SessionFixationStrategy.MIGRATE -> sessionFixation.migrateSession()
SessionFixationStrategy.CHANGE_ID -> sessionFixation.changeSessionId()
SessionFixationStrategy.NONE -> sessionFixation.none()
null -> null
}
}
}

View File

@ -12,8 +12,8 @@ base64 =
## Whether a string should be base64 encoded
attribute base64 {xsd:boolean}
request-matcher =
## Defines the strategy use for matching incoming requests. Currently the options are 'path' (for PathPatternRequestMatcher), 'regex' for regular expressions and 'ciRegex' for case-insensitive regular expressions.
attribute request-matcher {"path" | "regex" | "ciRegex"}
## Defines the strategy use for matching incoming requests. Currently the options are 'mvc' (for Spring MVC matcher), 'ant' (for ant path patterns), 'regex' for regular expressions and 'ciRegex' for case-insensitive regular expressions.
attribute request-matcher {"mvc" | "ant" | "regex" | "ciRegex"}
port =
## Specifies an IP port number. Used to configure an embedded LDAP server, for example.
attribute port { xsd:nonNegativeInteger }

View File

@ -27,14 +27,15 @@
<xs:attributeGroup name="request-matcher">
<xs:attribute name="request-matcher" use="required">
<xs:annotation>
<xs:documentation>Defines the strategy use for matching incoming requests. Currently the options are 'path'
(for PathPatternRequestMatcher), 'regex' for regular expressions and 'ciRegex' for
case-insensitive regular expressions.
<xs:documentation>Defines the strategy use for matching incoming requests. Currently the options are 'mvc'
(for Spring MVC matcher), 'ant' (for ant path patterns), 'regex' for regular expressions
and 'ciRegex' for case-insensitive regular expressions.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="path"/>
<xs:enumeration value="mvc"/>
<xs:enumeration value="ant"/>
<xs:enumeration value="regex"/>
<xs:enumeration value="ciRegex"/>
</xs:restriction>
@ -1305,14 +1306,15 @@
</xs:attribute>
<xs:attribute name="request-matcher">
<xs:annotation>
<xs:documentation>Defines the strategy use for matching incoming requests. Currently the options are 'path'
(for PathPatternRequestMatcher), 'regex' for regular expressions and 'ciRegex' for
case-insensitive regular expressions.
<xs:documentation>Defines the strategy use for matching incoming requests. Currently the options are 'mvc'
(for Spring MVC matcher), 'ant' (for ant path patterns), 'regex' for regular expressions
and 'ciRegex' for case-insensitive regular expressions.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="path"/>
<xs:enumeration value="mvc"/>
<xs:enumeration value="ant"/>
<xs:enumeration value="regex"/>
<xs:enumeration value="ciRegex"/>
</xs:restriction>
@ -2472,14 +2474,15 @@
<xs:attributeGroup name="filter-chain-map.attlist">
<xs:attribute name="request-matcher">
<xs:annotation>
<xs:documentation>Defines the strategy use for matching incoming requests. Currently the options are 'path'
(for PathPatternRequestMatcher), 'regex' for regular expressions and 'ciRegex' for
case-insensitive regular expressions.
<xs:documentation>Defines the strategy use for matching incoming requests. Currently the options are 'mvc'
(for Spring MVC matcher), 'ant' (for ant path patterns), 'regex' for regular expressions
and 'ciRegex' for case-insensitive regular expressions.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="path"/>
<xs:enumeration value="mvc"/>
<xs:enumeration value="ant"/>
<xs:enumeration value="regex"/>
<xs:enumeration value="ciRegex"/>
</xs:restriction>
@ -2577,14 +2580,15 @@
</xs:attribute>
<xs:attribute name="request-matcher">
<xs:annotation>
<xs:documentation>Defines the strategy use for matching incoming requests. Currently the options are 'path'
(for PathPatternRequestMatcher), 'regex' for regular expressions and 'ciRegex' for
case-insensitive regular expressions.
<xs:documentation>Defines the strategy use for matching incoming requests. Currently the options are 'mvc'
(for Spring MVC matcher), 'ant' (for ant path patterns), 'regex' for regular expressions
and 'ciRegex' for case-insensitive regular expressions.
</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="path"/>
<xs:enumeration value="mvc"/>
<xs:enumeration value="ant"/>
<xs:enumeration value="regex"/>
<xs:enumeration value="ciRegex"/>
</xs:restriction>

View File

@ -20,7 +20,6 @@ import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.security.Principal;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.Date;
@ -246,15 +245,12 @@ import org.springframework.security.web.savedrequest.SimpleSavedRequest;
import org.springframework.security.web.server.firewall.ServerExchangeRejectedException;
import org.springframework.security.web.session.HttpSessionCreatedEvent;
import org.springframework.security.web.session.HttpSessionIdChangedEvent;
import org.springframework.security.web.webauthn.api.AttestationConveyancePreference;
import org.springframework.security.web.webauthn.api.AuthenticationExtensionsClientInputs;
import org.springframework.security.web.webauthn.api.AuthenticationExtensionsClientOutputs;
import org.springframework.security.web.webauthn.api.AuthenticatorAssertionResponse;
import org.springframework.security.web.webauthn.api.AuthenticatorAttachment;
import org.springframework.security.web.webauthn.api.AuthenticatorSelectionCriteria;
import org.springframework.security.web.webauthn.api.AuthenticatorTransport;
import org.springframework.security.web.webauthn.api.Bytes;
import org.springframework.security.web.webauthn.api.COSEAlgorithmIdentifier;
import org.springframework.security.web.webauthn.api.CredProtectAuthenticationExtensionsClientInput;
import org.springframework.security.web.webauthn.api.CredentialPropertiesOutput;
import org.springframework.security.web.webauthn.api.ImmutableAuthenticationExtensionsClientInput;
@ -262,17 +258,12 @@ import org.springframework.security.web.webauthn.api.ImmutableAuthenticationExte
import org.springframework.security.web.webauthn.api.ImmutableAuthenticationExtensionsClientOutputs;
import org.springframework.security.web.webauthn.api.ImmutablePublicKeyCredentialUserEntity;
import org.springframework.security.web.webauthn.api.PublicKeyCredential;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialCreationOptions;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialDescriptor;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialParameters;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialRequestOptions;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialRpEntity;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialType;
import org.springframework.security.web.webauthn.api.PublicKeyCredentialUserEntity;
import org.springframework.security.web.webauthn.api.ResidentKeyRequirement;
import org.springframework.security.web.webauthn.api.TestAuthenticationAssertionResponses;
import org.springframework.security.web.webauthn.api.TestBytes;
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialCreationOptions;
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialRequestOptions;
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentialUserEntities;
import org.springframework.security.web.webauthn.api.TestPublicKeyCredentials;
@ -280,7 +271,6 @@ import org.springframework.security.web.webauthn.api.UserVerificationRequirement
import org.springframework.security.web.webauthn.authentication.WebAuthnAuthentication;
import org.springframework.security.web.webauthn.authentication.WebAuthnAuthenticationRequestToken;
import org.springframework.security.web.webauthn.management.RelyingPartyAuthenticationRequest;
import org.springframework.security.web.webauthn.management.TestPublicKeyCredentialRpEntities;
import org.springframework.util.ReflectionUtils;
final class SerializationSamples {
@ -294,14 +284,6 @@ final class SerializationSamples {
Authentication authentication = TestAuthentication.authenticated(user);
SecurityContext securityContext = new SecurityContextImpl(authentication);
instancioByClassName.put(OneTimeTokenAuthenticationToken.class, () -> {
@SuppressWarnings("removal")
InstancioOfClassApi<?> instancio = Instancio.of(OneTimeTokenAuthenticationToken.class);
instancio.supply(Select.all(OneTimeTokenAuthenticationToken.class),
(r) -> applyDetails(new OneTimeTokenAuthenticationToken("token")));
return instancio;
});
// oauth2-core
generatorByClassName.put(DefaultOAuth2User.class, (r) -> TestOAuth2Users.create());
generatorByClassName.put(OAuth2AuthorizationRequest.class,
@ -615,7 +597,8 @@ final class SerializationSamples {
token.setDetails(details);
return token;
});
generatorByClassName.put(OneTimeTokenAuthenticationToken.class,
(r) -> applyDetails(new OneTimeTokenAuthenticationToken("username", "token")));
generatorByClassName.put(OneTimeTokenAuthentication.class,
(r) -> applyDetails(new OneTimeTokenAuthentication("username", authentication.getAuthorities())));
generatorByClassName.put(AccessDeniedException.class,
@ -896,36 +879,6 @@ final class SerializationSamples {
generatorByClassName.put(CredentialPropertiesOutput.ExtensionOutput.class,
(r) -> new CredentialPropertiesOutput(true).getOutput());
AttestationConveyancePreference attestationConveyancePreference = AttestationConveyancePreference.DIRECT;
ResidentKeyRequirement residentKeyRequirement = ResidentKeyRequirement.REQUIRED;
AuthenticatorSelectionCriteria authenticatorSelectionCriteria = AuthenticatorSelectionCriteria.builder()
.authenticatorAttachment(AuthenticatorAttachment.PLATFORM)
.residentKey(residentKeyRequirement)
.userVerification(UserVerificationRequirement.REQUIRED)
.build();
PublicKeyCredentialParameters publicKeyCredentialParameters = PublicKeyCredentialParameters.RS256;
PublicKeyCredentialRpEntity publicKeyCredentialRpEntity = TestPublicKeyCredentialRpEntities.createRpEntity()
.build();
generatorByClassName.put(AttestationConveyancePreference.class, (r) -> attestationConveyancePreference);
generatorByClassName.put(ResidentKeyRequirement.class, (r) -> residentKeyRequirement);
generatorByClassName.put(AuthenticatorSelectionCriteria.class, (r) -> authenticatorSelectionCriteria);
generatorByClassName.put(COSEAlgorithmIdentifier.class, ((r) -> COSEAlgorithmIdentifier.RS256));
generatorByClassName.put(PublicKeyCredentialParameters.class, (r) -> publicKeyCredentialParameters);
generatorByClassName.put(PublicKeyCredentialRpEntity.class, (r) -> publicKeyCredentialRpEntity);
generatorByClassName.put(PublicKeyCredentialCreationOptions.class,
(o) -> TestPublicKeyCredentialCreationOptions.createPublicKeyCredentialCreationOptions()
.extensions(inputs)
.attestation(attestationConveyancePreference)
.authenticatorSelection(authenticatorSelectionCriteria)
.challenge(TestBytes.get())
.excludeCredentials(List.of(descriptor))
.rp(publicKeyCredentialRpEntity)
.pubKeyCredParams(publicKeyCredentialParameters)
.timeout(Duration.ofMinutes(5))
.user(TestPublicKeyCredentialUserEntities.userEntity().id(TestBytes.get()).build())
.build());
// One-Time Token
DefaultOneTimeToken oneTimeToken = new DefaultOneTimeToken(UUID.randomUUID().toString(), "user",
Instant.now().plusSeconds(300));

View File

@ -197,7 +197,7 @@ public class NamespaceHttpTests {
// @formatter:off
this.mockMvc.perform(get("/"))
.andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"RealmConfig\", charset=\"UTF-8\""));
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"RealmConfig\""));
// @formatter:on
}

View File

@ -222,8 +222,7 @@ public class WebSecurityConfigurationTests {
// SEC-2773
@Test
public void getMethodDelegatingApplicationListenerWhenWebSecurityConfigurationThenIsStatic() {
Method method = ClassUtils.getMethod(WebSecurityConfiguration.class, "delegatingApplicationListener",
(Class<?>[]) null);
Method method = ClassUtils.getMethod(WebSecurityConfiguration.class, "delegatingApplicationListener", null);
assertThat(Modifier.isStatic(method.getModifiers())).isTrue();
}

View File

@ -1201,7 +1201,6 @@ public class HeadersConfigurerTests {
@Configuration
@EnableWebSecurity
@SuppressWarnings("removal")
static class PermissionsPolicyConfig {
@Bean
@ -1222,7 +1221,6 @@ public class HeadersConfigurerTests {
static class PermissionsPolicyStringConfig {
@Bean
@SuppressWarnings("removal")
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// @formatter:off
http
@ -1237,7 +1235,6 @@ public class HeadersConfigurerTests {
@Configuration
@EnableWebSecurity
@SuppressWarnings("removal")
static class PermissionsPolicyInvalidConfig {
@Bean
@ -1255,7 +1252,6 @@ public class HeadersConfigurerTests {
@Configuration
@EnableWebSecurity
@SuppressWarnings("removal")
static class PermissionsPolicyInvalidStringConfig {
@Bean

View File

@ -103,7 +103,7 @@ public class HttpBasicConfigurerTests {
// @formatter:off
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\", charset=\"UTF-8\""));
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
// @formatter:on
}
@ -114,7 +114,7 @@ public class HttpBasicConfigurerTests {
// @formatter:off
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\", charset=\"UTF-8\""));
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
// @formatter:on
}

View File

@ -71,7 +71,7 @@ public class NamespaceHttpBasicTests {
// @formatter:off
this.mvc.perform(requestWithInvalidPassword)
.andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Realm\", charset=\"UTF-8\""));
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Realm\""));
// @formatter:on
MockHttpServletRequestBuilder requestWithValidPassword = get("/").with(httpBasic("user", "password"));
this.mvc.perform(requestWithValidPassword).andExpect(status().isNotFound());
@ -85,7 +85,7 @@ public class NamespaceHttpBasicTests {
// @formatter:off
this.mvc.perform(requestWithInvalidPassword)
.andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Realm\", charset=\"UTF-8\""));
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Realm\""));
// @formatter:on
MockHttpServletRequestBuilder requestWithValidPassword = get("/").with(httpBasic("user", "password"));
this.mvc.perform(requestWithValidPassword).andExpect(status().isNotFound());
@ -101,7 +101,7 @@ public class NamespaceHttpBasicTests {
// @formatter:off
this.mvc.perform(requestWithInvalidPassword)
.andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\", charset=\"UTF-8\""));
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\""));
// @formatter:on
}
@ -112,7 +112,7 @@ public class NamespaceHttpBasicTests {
// @formatter:off
this.mvc.perform(requestWithInvalidPassword)
.andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\", charset=\"UTF-8\""));
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\""));
// @formatter:on
}

View File

@ -1257,7 +1257,6 @@ public class OAuth2AuthorizationCodeGrantTests {
}
@Bean
@SuppressWarnings("removal")
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(
jdbcOperations);

View File

@ -561,7 +561,6 @@ public class OAuth2ClientCredentialsGrantTests {
}
@Bean
@SuppressWarnings("removal")
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(
jdbcOperations);

View File

@ -411,30 +411,6 @@ public class OAuth2ClientRegistrationTests {
.isCloseTo(expectedSecretExpiryDate, allowedDelta);
}
@Test
public void requestWhenClientRegistersWithCustomTokenSettingsThenSavedToRegisteredClient() throws Exception {
this.spring.register(CustomTokenSettingsConfiguration.class).autowire();
// @formatter:off
OAuth2ClientRegistration clientRegistration = OAuth2ClientRegistration.builder()
.clientName("client-name")
.redirectUri("https://client.example.com")
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
.scope("scope1")
.scope("scope2")
.build();
// @formatter:on
OAuth2ClientRegistration clientRegistrationResponse = registerClient(clientRegistration);
RegisteredClient registeredClient = this.registeredClientRepository
.findByClientId(clientRegistrationResponse.getClientId());
assertThat(registeredClient).isNotNull();
assertThat(registeredClient.getTokenSettings().getAccessTokenTimeToLive()).isEqualTo(Duration.ofMinutes(60));
}
private OAuth2ClientRegistration registerClient(OAuth2ClientRegistration clientRegistration) throws Exception {
// ***** (1) Obtain the "initial" access token used for registering the client
@ -624,44 +600,6 @@ public class OAuth2ClientRegistrationTests {
}
@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
static class CustomTokenSettingsConfiguration extends AuthorizationServerConfiguration {
// @formatter:off
@Bean
@Override
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
http
.oauth2AuthorizationServer((authorizationServer) ->
authorizationServer
.clientRegistrationEndpoint((clientRegistration) ->
clientRegistration
.authenticationProviders(configureClientRegistrationConverters())
)
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
);
return http.build();
}
// @formatter:on
private Consumer<List<AuthenticationProvider>> configureClientRegistrationConverters() {
// @formatter:off
return (authenticationProviders) ->
authenticationProviders.forEach((authenticationProvider) -> {
if (authenticationProvider instanceof OAuth2ClientRegistrationAuthenticationProvider provider) {
OAuth2ClientRegistrationRegisteredClientConverter clientRegistrationRegisteredClientConverter = new OAuth2ClientRegistrationRegisteredClientConverter();
clientRegistrationRegisteredClientConverter.setTokenSettingsCustomizer((tokenSettings) -> tokenSettings.accessTokenTimeToLive(Duration.ofMinutes(60)));
provider.setRegisteredClientConverter(clientRegistrationRegisteredClientConverter);
}
});
// @formatter:on
}
}
@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
static class OpenClientRegistrationConfiguration extends AuthorizationServerConfiguration {
@ -709,7 +647,6 @@ public class OAuth2ClientRegistrationTests {
// @formatter:on
@Bean
@SuppressWarnings("removal")
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();

View File

@ -359,7 +359,7 @@ public class OAuth2DeviceCodeGrantTests {
}
@Test
public void requestWhenDeviceAuthorizationConsentRequestUnauthenticatedThenUnauthorized() throws Exception {
public void requestWhenDeviceAuthorizationConsentRequestUnauthenticatedThenBadRequest() throws Exception {
this.spring.register(AuthorizationServerConfiguration.class).autowire();
// @formatter:off
@ -392,7 +392,7 @@ public class OAuth2DeviceCodeGrantTests {
// @formatter:off
this.mvc.perform(post(DEFAULT_DEVICE_VERIFICATION_ENDPOINT_URI)
.params(parameters))
.andExpect(status().isUnauthorized());
.andExpect(status().isBadRequest());
// @formatter:on
}

View File

@ -469,7 +469,6 @@ public class OAuth2RefreshTokenGrantTests {
}
@Bean
@SuppressWarnings("removal")
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(
jdbcOperations);

View File

@ -515,7 +515,6 @@ public class OAuth2TokenIntrospectionTests {
}
@Bean
@SuppressWarnings("removal")
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(
jdbcOperations);

View File

@ -318,7 +318,6 @@ public class OAuth2TokenRevocationTests {
}
@Bean
@SuppressWarnings("removal")
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(
jdbcOperations);

View File

@ -778,7 +778,6 @@ public class OidcClientRegistrationTests {
// @formatter:on
@Bean
@SuppressWarnings("removal")
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
RegisteredClientParametersMapper registeredClientParametersMapper = new RegisteredClientParametersMapper();

View File

@ -633,7 +633,6 @@ public class OidcTests {
}
@Bean
@SuppressWarnings("removal")
RegisteredClientRepository registeredClientRepository(JdbcOperations jdbcOperations) {
JdbcRegisteredClientRepository jdbcRegisteredClientRepository = new JdbcRegisteredClientRepository(
jdbcOperations);

View File

@ -107,7 +107,7 @@ public class ServerHttpSecurityConfigurationTests {
}
@Test
public void loadConfigWhenReactiveUserAuthenticationServiceConfiguredThenServerHttpSecurityExists() {
public void loadConfigWhenReactiveUserDetailsServiceConfiguredThenServerHttpSecurityExists() {
this.spring
.register(ServerHttpSecurityConfiguration.class, ReactiveAuthenticationTestConfiguration.class,
WebFluxSecurityConfiguration.class)
@ -116,16 +116,6 @@ public class ServerHttpSecurityConfigurationTests {
assertThat(serverHttpSecurity).isNotNull();
}
@Test
public void loadConfigWhenOnlyReactiveUserDetailsServiceConfiguredThenServerHttpSecurityExists() {
this.spring
.register(ServerHttpSecurityConfiguration.class, ReactiveUserDetailsServiceOnlyTestConfiguration.class,
WebFluxSecurityConfiguration.class)
.autowire();
ServerHttpSecurity serverHttpSecurity = this.spring.getContext().getBean(ServerHttpSecurity.class);
assertThat(serverHttpSecurity).isNotNull();
}
@Test
public void loadConfigWhenProxyingEnabledAndSubclassThenServerHttpSecurityExists() {
this.spring
@ -591,14 +581,4 @@ public class ServerHttpSecurityConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class ReactiveUserDetailsServiceOnlyTestConfiguration {
@Bean
static ReactiveUserDetailsService userDetailsService() {
return (username) -> Mono.just(PasswordEncodedUser.user());
}
}
}

View File

@ -337,54 +337,6 @@ public class InterceptUrlConfigTests {
assertThat(this.spring.getContext().getBean(AuthorizationManager.class)).isNotNull();
}
/**
* gh-18503
*/
@Test
public void configWhenInterceptUrlMissingAccessThenException() {
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() -> this.spring.configLocations(this.xml("MissingAccess")).autowire())
.withMessageContaining("access attribute cannot be empty or null");
}
/**
* gh-18503
*/
@Test
public void configWhenInterceptUrlEmptyAccessThenException() {
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() -> this.spring.configLocations(this.xml("EmptyAccess")).autowire())
.withMessageContaining("access attribute cannot be empty or null");
}
/**
* gh-18503
*/
@Test
public void configWhenInterceptUrlValidAccessThenLoads() {
assertThatNoException().isThrownBy(() -> this.spring.configLocations(this.xml("ValidAccess")).autowire());
}
/**
* gh-18503
*/
@Test
public void configWhenUseAuthorizationManagerFalseAndMissingAccessThenException() {
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() -> this.spring.configLocations(this.xml("MissingAccessLegacy")).autowire())
.withMessageContaining("access attribute cannot be empty or null");
}
/**
* gh-18503
*/
@Test
public void configWhenUseAuthorizationManagerFalseAndEmptyAccessThenException() {
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() -> this.spring.configLocations(this.xml("EmptyAccessLegacy")).autowire())
.withMessageContaining("access attribute cannot be empty or null");
}
private static RequestPostProcessor adminCredentials() {
return httpBasic("admin", "password");
}

View File

@ -133,7 +133,7 @@ public class NamespaceHttpBasicTests {
// @formatter:on
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getHeader("WWW-Authenticate")).isEqualTo("Basic realm=\"Realm\", charset=\"UTF-8\"");
assertThat(this.response.getHeader("WWW-Authenticate")).isEqualTo("Basic realm=\"Realm\"");
}
private void loadContext(String context) {

View File

@ -100,7 +100,6 @@ import static org.mockito.Mockito.verify;
* {@link org.springframework.security.config.web.server.ServerHttpSecurity.OAuth2ResourceServerSpec}
*/
@ExtendWith({ SpringTestContextExtension.class })
@SuppressWarnings("removal")
public class OAuth2ResourceServerSpecTests {
private String expired = "eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE1MzUwMzc4OTd9.jqZDDjfc2eysX44lHXEIr9XFd2S8vjIZHCccZU-dRWMRJNsQ1QN5VNnJGklqJBXJR4qgla6cmVqPOLkUHDb0sL0nxM5XuzQaG5ZzKP81RV88shFyAiT0fD-6nl1k-Fai-Fu-VkzSpNXgeONoTxDaYhdB-yxmgrgsApgmbOTE_9AcMk-FQDXQ-pL9kynccFGV0lZx4CA7cyknKN7KBxUilfIycvXODwgKCjj_1WddLTCNGYogJJSg__7NoxzqbyWd3udbHVjqYq7GsMMrGB4_2kBD4CkghOSNcRHbT_DIXowxfAVT7PAg7Q0E5ruZsr2zPZacEUDhJ6-wbvlA0FAOUg";

View File

@ -167,7 +167,6 @@ public class OidcLogoutSpecTests {
}
@Test
@SuppressWarnings("removal")
void logoutWhenInvalidLogoutTokenThenBadRequest() {
this.spring.register(WebServerConfig.class, OidcProviderConfig.class, DefaultConfig.class).autowire();
this.test.get().uri("/token/logout").exchange().expectStatus().isUnauthorized();
@ -210,7 +209,6 @@ public class OidcLogoutSpecTests {
}
@Test
@SuppressWarnings("removal")
void logoutWhenLogoutTokenSpecifiesOneSessionThenRemotelyInvalidatesOnlyThatSession() throws Exception {
this.spring.register(WebServerConfig.class, OidcProviderConfig.class, DefaultConfig.class).autowire();
String registrationId = this.clientRegistration.getRegistrationId();
@ -254,7 +252,6 @@ public class OidcLogoutSpecTests {
}
@Test
@SuppressWarnings("removal")
void logoutWhenRemoteLogoutUriThenUses() {
this.spring.register(WebServerConfig.class, OidcProviderConfig.class, LogoutUriConfig.class).autowire();
String registrationId = this.clientRegistration.getRegistrationId();
@ -305,7 +302,6 @@ public class OidcLogoutSpecTests {
}
@Test
@SuppressWarnings("removal")
void logoutWhenDifferentCookieNameThenUses() {
this.spring.register(OidcProviderConfig.class, CookieConfig.class).autowire();
String registrationId = this.clientRegistration.getRegistrationId();
@ -329,7 +325,6 @@ public class OidcLogoutSpecTests {
}
@Test
@SuppressWarnings("removal")
void logoutWhenRemoteLogoutFailsThenReportsPartialLogout() {
this.spring.register(WebServerConfig.class, OidcProviderConfig.class, WithBrokenLogoutConfig.class).autowire();
ServerLogoutHandler logoutHandler = this.spring.getContext().getBean(ServerLogoutHandler.class);

View File

@ -737,7 +737,6 @@ public class ServerHttpSecurityTests {
}
@Test
@SuppressWarnings("removal")
void resourcesWhenLoginPageConfiguredThenServesCss() {
this.http.formLogin(withDefaults());
this.http.authenticationManager(this.authenticationManager);

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*
@ -74,7 +72,7 @@ class HttpBasicDslTests {
this.mockMvc.get("/")
.andExpect {
header { string("WWW-Authenticate", "Basic realm=\"Realm\", charset=\"UTF-8\"") }
header { string("WWW-Authenticate", "Basic realm=\"Realm\"") }
}
}
@ -110,7 +108,7 @@ class HttpBasicDslTests {
this.mockMvc.get("/")
.andExpect {
header { string("WWW-Authenticate", "Basic realm=\"Custom Realm\", charset=\"UTF-8\"") }
header { string("WWW-Authenticate", "Basic realm=\"Custom Realm\"") }
}
}

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -1,5 +1,3 @@
@file:Suppress("DEPRECATION", "PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST")
/*
* Copyright 2004-present the original author or authors.
*

View File

@ -24,7 +24,7 @@
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<http request-matcher="path" use-authorization-manager="false">
<http request-matcher="ant" use-authorization-manager="false">
<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
<http-basic/>
</http>

View File

@ -24,7 +24,7 @@
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<http request-matcher="path">
<http request-matcher="ant">
<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
<http-basic/>
</http>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<http>
<intercept-url pattern="/admin/**" access="" />
</http>
<user-service>
<user name="user" password="{noop}password" authorities="ROLE_USER"/>
</user-service>
</b:beans>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<http use-authorization-manager="false">
<intercept-url pattern="/admin/**" access=""/>
</http>
<user-service>
<user name="user" password="{noop}password" authorities="ROLE_USER"/>
</user-service>
</b:beans>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<http>
<intercept-url pattern="/admin/**"/>
</http>
<user-service>
<user name="user" password="{noop}password" authorities="ROLE_USER"/>
</user-service>
</b:beans>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<http use-authorization-manager="false">
<intercept-url pattern="/admin/**"/>
</http>
<user-service>
<user name="user" password="{noop}password" authorities="ROLE_USER"/>
</user-service>
</b:beans>

View File

@ -27,7 +27,7 @@
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<http auto-config="true" request-matcher="path" use-authorization-manager="false">
<http auto-config="true" request-matcher="mvc" use-authorization-manager="false">
<intercept-url pattern="/path" access="denyAll"/>
<http-basic/>
</http>

View File

@ -27,7 +27,7 @@
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<http auto-config="true" request-matcher="path">
<http auto-config="true" request-matcher="mvc">
<intercept-url pattern="/path" access="denyAll"/>
<http-basic/>
</http>

View File

@ -27,7 +27,7 @@
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<http auto-config="true" request-matcher="path" use-authorization-manager="false">
<http auto-config="true" request-matcher="mvc" use-authorization-manager="false">
<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
<http-basic/>
</http>

View File

@ -27,7 +27,7 @@
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<http auto-config="true" request-matcher="path">
<http auto-config="true" request-matcher="mvc">
<intercept-url pattern="/path" access="denyAll" servlet-path="/spring"/>
<http-basic/>
</http>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<http>
<intercept-url pattern="/admin/**" access="hasRole('ADMIN')" />
<http-basic />
</http>
<user-service>
<user name="user" password="{noop}password" authorities="ROLE_USER"/>
</user-service>
</b:beans>

View File

@ -18,8 +18,6 @@ package org.springframework.security.access;
import java.io.Serializable;
import org.jspecify.annotations.Nullable;
import org.springframework.aop.framework.AopInfrastructureBean;
import org.springframework.security.core.Authentication;
@ -41,7 +39,7 @@ public interface PermissionEvaluator extends AopInfrastructureBean {
* expression system. Not null.
* @return true if the permission is granted, false otherwise
*/
boolean hasPermission(Authentication authentication, @Nullable Object targetDomainObject, Object permission);
boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission);
/**
* Alternative method for evaluating a permission where only the identifier of the

View File

@ -20,7 +20,6 @@ import java.io.Serializable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.core.log.LogMessage;
import org.springframework.security.access.PermissionEvaluator;
@ -41,7 +40,7 @@ public class DenyAllPermissionEvaluator implements PermissionEvaluator {
* @return false always
*/
@Override
public boolean hasPermission(Authentication authentication, @Nullable Object target, Object permission) {
public boolean hasPermission(Authentication authentication, Object target, Object permission) {
this.logger.warn(LogMessage.format("Denying user %s permission '%s' on object %s", authentication.getName(),
permission, target));
return false;

View File

@ -38,7 +38,6 @@ import org.springframework.util.function.SingletonSupplier;
* @author Luke Taylor
* @author Evgeniy Cheban
* @author Steve Riesenberg
* @author Ngoc Nhan
* @since 3.0
*/
public abstract class SecurityExpressionRoot<T extends @Nullable Object> implements SecurityExpressionOperations {
@ -117,7 +116,7 @@ public abstract class SecurityExpressionRoot<T extends @Nullable Object> impleme
@Override
public final boolean hasAuthority(String authority) {
return isGranted(this.authorizationManagerFactory.hasAuthority(authority));
return isGranted(this.authorizationManagerFactory.hasAnyAuthority(authority));
}
@Override
@ -209,8 +208,7 @@ public abstract class SecurityExpressionRoot<T extends @Nullable Object> impleme
/**
* Convenience method to access {@link Authentication#getPrincipal()} from
* {@link #getAuthentication()}
* @return the {@code Principal} being authenticated or the authenticated principal
* after authentication.
* @return
*/
public @Nullable Object getPrincipal() {
return getAuthentication().getPrincipal();

Some files were not shown because too many files have changed in this diff Show More