Require Locale argument for toLower/toUpperCase usage

This commit is contained in:
Joe Grandja 2024-10-28 07:38:45 -04:00
parent e86d88d0cf
commit 0eaffb37e7
23 changed files with 97 additions and 50 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.security.cas.userdetails;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
import org.jasig.cas.client.validation.Assertion; import org.jasig.cas.client.validation.Assertion;
@ -73,7 +74,8 @@ public final class GrantedAuthorityFromAssertionAttributesUserDetailsService
} }
private SimpleGrantedAuthority createSimpleGrantedAuthority(Object o) { private SimpleGrantedAuthority createSimpleGrantedAuthority(Object o) {
return new SimpleGrantedAuthority(this.convertToUpperCase ? o.toString().toUpperCase() : o.toString()); return new SimpleGrantedAuthority(
this.convertToUpperCase ? o.toString().toUpperCase(Locale.ROOT) : o.toString());
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.security.config.http;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
@ -286,7 +287,7 @@ class HttpConfigurationBuilder {
// Needed to account for placeholders // Needed to account for placeholders
static String createPath(String path, boolean lowerCase) { static String createPath(String path, boolean lowerCase) {
return lowerCase ? path.toLowerCase() : path; return lowerCase ? path.toLowerCase(Locale.ENGLISH) : path;
} }
BeanReference getSecurityContextRepositoryForAuthenticationFilters() { BeanReference getSecurityContextRepositoryForAuthenticationFilters() {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -79,10 +79,10 @@ public class SimpleAttributes2GrantedAuthoritiesMapper
*/ */
private GrantedAuthority getGrantedAuthority(String attribute) { private GrantedAuthority getGrantedAuthority(String attribute) {
if (isConvertAttributeToLowerCase()) { if (isConvertAttributeToLowerCase()) {
attribute = attribute.toLowerCase(Locale.getDefault()); attribute = attribute.toLowerCase(Locale.ROOT);
} }
else if (isConvertAttributeToUpperCase()) { else if (isConvertAttributeToUpperCase()) {
attribute = attribute.toUpperCase(Locale.getDefault()); attribute = attribute.toUpperCase(Locale.ROOT);
} }
if (isAddPrefixIfAlreadyExisting() || !attribute.startsWith(getAttributePrefix())) { if (isAddPrefixIfAlreadyExisting() || !attribute.startsWith(getAttributePrefix())) {
return new SimpleGrantedAuthority(getAttributePrefix() + attribute); return new SimpleGrantedAuthority(getAttributePrefix() + attribute);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.security.core.authority.mapping;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale;
import java.util.Set; import java.util.Set;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
@ -71,10 +72,10 @@ public final class SimpleAuthorityMapper implements GrantedAuthoritiesMapper, In
private GrantedAuthority mapAuthority(String name) { private GrantedAuthority mapAuthority(String name) {
if (this.convertToUpperCase) { if (this.convertToUpperCase) {
name = name.toUpperCase(); name = name.toUpperCase(Locale.ROOT);
} }
else if (this.convertToLowerCase) { else if (this.convertToLowerCase) {
name = name.toLowerCase(); name = name.toLowerCase(Locale.ROOT);
} }
if (this.prefix.length() > 0 && !name.startsWith(this.prefix)) { if (this.prefix.length() > 0 && !name.startsWith(this.prefix)) {
name = this.prefix + name; name = this.prefix + name;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.security.core.userdetails;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -91,7 +92,7 @@ public class MapReactiveUserDetailsService implements ReactiveUserDetailsService
} }
private String getKey(String username) { private String getKey(String username) {
return username.toLowerCase(); return username.toLowerCase(Locale.ROOT);
} }
} }

View File

@ -19,6 +19,7 @@ package org.springframework.security.core.userdetails.memory;
import java.beans.PropertyEditorSupport; import java.beans.PropertyEditorSupport;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -45,10 +46,10 @@ public class UserAttributeEditor extends PropertyEditorSupport {
userAttrib.setPassword(currentToken); userAttrib.setPassword(currentToken);
} }
else { else {
if (currentToken.toLowerCase().equals("enabled")) { if (currentToken.toLowerCase(Locale.ENGLISH).equals("enabled")) {
userAttrib.setEnabled(true); userAttrib.setEnabled(true);
} }
else if (currentToken.toLowerCase().equals("disabled")) { else if (currentToken.toLowerCase(Locale.ENGLISH).equals("disabled")) {
userAttrib.setEnabled(false); userAttrib.setEnabled(false);
} }
else { else {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.security.provisioning;
import java.util.Collection; import java.util.Collection;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -92,23 +93,23 @@ public class InMemoryUserDetailsManager implements UserDetailsManager, UserDetai
@Override @Override
public void createUser(UserDetails user) { public void createUser(UserDetails user) {
Assert.isTrue(!userExists(user.getUsername()), "user should not exist"); Assert.isTrue(!userExists(user.getUsername()), "user should not exist");
this.users.put(user.getUsername().toLowerCase(), new MutableUser(user)); this.users.put(user.getUsername().toLowerCase(Locale.ROOT), new MutableUser(user));
} }
@Override @Override
public void deleteUser(String username) { public void deleteUser(String username) {
this.users.remove(username.toLowerCase()); this.users.remove(username.toLowerCase(Locale.ROOT));
} }
@Override @Override
public void updateUser(UserDetails user) { public void updateUser(UserDetails user) {
Assert.isTrue(userExists(user.getUsername()), "user should exist"); Assert.isTrue(userExists(user.getUsername()), "user should exist");
this.users.put(user.getUsername().toLowerCase(), new MutableUser(user)); this.users.put(user.getUsername().toLowerCase(Locale.ROOT), new MutableUser(user));
} }
@Override @Override
public boolean userExists(String username) { public boolean userExists(String username) {
return this.users.containsKey(username.toLowerCase()); return this.users.containsKey(username.toLowerCase(Locale.ROOT));
} }
@Override @Override
@ -139,14 +140,14 @@ public class InMemoryUserDetailsManager implements UserDetailsManager, UserDetai
@Override @Override
public UserDetails updatePassword(UserDetails user, String newPassword) { public UserDetails updatePassword(UserDetails user, String newPassword) {
String username = user.getUsername(); String username = user.getUsername();
MutableUserDetails mutableUser = this.users.get(username.toLowerCase()); MutableUserDetails mutableUser = this.users.get(username.toLowerCase(Locale.ROOT));
mutableUser.setPassword(newPassword); mutableUser.setPassword(newPassword);
return mutableUser; return mutableUser;
} }
@Override @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserDetails user = this.users.get(username.toLowerCase()); UserDetails user = this.users.get(username.toLowerCase(Locale.ROOT));
if (user == null) { if (user == null) {
throw new UsernameNotFoundException(username); throw new UsernameNotFoundException(username);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.security.crypto.password;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.util.Base64; import java.util.Base64;
import java.util.Locale;
import org.springframework.security.crypto.codec.Utf8; import org.springframework.security.crypto.codec.Utf8;
import org.springframework.security.crypto.keygen.BytesKeyGenerator; import org.springframework.security.crypto.keygen.BytesKeyGenerator;
@ -50,11 +51,11 @@ public class LdapShaPasswordEncoder implements PasswordEncoder {
private static final String SSHA_PREFIX = "{SSHA}"; private static final String SSHA_PREFIX = "{SSHA}";
private static final String SSHA_PREFIX_LC = SSHA_PREFIX.toLowerCase(); private static final String SSHA_PREFIX_LC = SSHA_PREFIX.toLowerCase(Locale.ENGLISH);
private static final String SHA_PREFIX = "{SHA}"; private static final String SHA_PREFIX = "{SHA}";
private static final String SHA_PREFIX_LC = SHA_PREFIX.toLowerCase(); private static final String SHA_PREFIX_LC = SHA_PREFIX.toLowerCase(Locale.ENGLISH);
private BytesKeyGenerator saltGenerator; private BytesKeyGenerator saltGenerator;

View File

@ -53,4 +53,11 @@
<suppress files="WithSecurityContextTestExecutionListenerTests\.java" checks="SpringMethodVisibility"/> <suppress files="WithSecurityContextTestExecutionListenerTests\.java" checks="SpringMethodVisibility"/>
<suppress files="AbstractOAuth2AuthorizationGrantRequestEntityConverter\.java" checks="SpringMethodVisibility"/> <suppress files="AbstractOAuth2AuthorizationGrantRequestEntityConverter\.java" checks="SpringMethodVisibility"/>
<suppress files="JoseHeader\.java" checks="SpringMethodVisibility"/> <suppress files="JoseHeader\.java" checks="SpringMethodVisibility"/>
<!-- Lambdas that we can't replace with a method reference because a closure is required -->
<suppress files="BearerTokenAuthenticationFilter\.java" checks="SpringLambda"/>
<!-- Ignore String.toUpperCase() and String.toLowerCase() checks in tests -->
<suppress files="[\\/]src[\\/]test[\\/]" checks="RegexpSinglelineJava" id="toLowerCaseWithoutLocale"/>
<suppress files="[\\/]src[\\/]test[\\/]" checks="RegexpSinglelineJava" id="toUpperCaseWithoutLocale"/>
</suppressions> </suppressions>

View File

@ -23,5 +23,21 @@
<property name="message" value="Please use assertThatExceptionOfType." /> <property name="message" value="Please use assertThatExceptionOfType." />
<property name="ignoreComments" value="true" /> <property name="ignoreComments" value="true" />
</module> </module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="id" value="toLowerCaseWithoutLocale"/>
<property name="format" value="\.toLowerCase\(\)"/>
<property name="maximum" value="0"/>
<property name="message"
value="String.toLowerCase() should be String.toLowerCase(Locale.ROOT) or String.toLowerCase(Locale.ENGLISH)"/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="id" value="toUpperCaseWithoutLocale"/>
<property name="format" value="\.toUpperCase\(\)"/>
<property name="maximum" value="0"/>
<property name="message"
value="String.toUpperCase() should be String.toUpperCase(Locale.ROOT) or String.toUpperCase(Locale.ENGLISH)"/>
<property name="ignoreComments" value="true"/>
</module>
</module> </module>
</module> </module>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2010 the original author or authors. * Copyright 2005-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.security.ldap; package org.springframework.security.ldap;
import java.util.Locale;
import org.springframework.ldap.BadLdapGrammarException; import org.springframework.ldap.BadLdapGrammarException;
/** /**
@ -72,7 +74,7 @@ final class LdapEncoder {
} }
protected static String toTwoCharHex(char c) { protected static String toTwoCharHex(char c) {
String raw = Integer.toHexString(c).toUpperCase(); String raw = Integer.toHexString(c).toUpperCase(Locale.ENGLISH);
return (raw.length() > 1) ? raw : "0" + raw; return (raw.length() > 1) ? raw : "0" + raw;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2010 the original author or authors. * Copyright 2005-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.security.ldap.authentication; package org.springframework.security.ldap.authentication;
import java.util.Locale;
import org.springframework.ldap.BadLdapGrammarException; import org.springframework.ldap.BadLdapGrammarException;
/** /**
@ -72,7 +74,7 @@ final class LdapEncoder {
} }
protected static String toTwoCharHex(char c) { protected static String toTwoCharHex(char c) {
String raw = Integer.toHexString(c).toUpperCase(); String raw = Integer.toHexString(c).toUpperCase(Locale.ENGLISH);
return (raw.length() > 1) ? raw : "0" + raw; return (raw.length() > 1) ? raw : "0" + raw;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -142,9 +143,9 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda
*/ */
public ActiveDirectoryLdapAuthenticationProvider(String domain, String url, String rootDn) { public ActiveDirectoryLdapAuthenticationProvider(String domain, String url, String rootDn) {
Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty"); Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty");
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null; this.domain = StringUtils.hasText(domain) ? domain.toLowerCase(Locale.ROOT) : null;
this.url = url; this.url = url;
this.rootDn = StringUtils.hasText(rootDn) ? rootDn.toLowerCase() : null; this.rootDn = StringUtils.hasText(rootDn) ? rootDn.toLowerCase(Locale.ROOT) : null;
} }
/** /**
@ -153,7 +154,7 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda
*/ */
public ActiveDirectoryLdapAuthenticationProvider(String domain, String url) { public ActiveDirectoryLdapAuthenticationProvider(String domain, String url) {
Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty"); Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty");
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null; this.domain = StringUtils.hasText(domain) ? domain.toLowerCase(Locale.ROOT) : null;
this.url = url; this.url = url;
this.rootDn = (this.domain != null) ? rootDnFromDomain(this.domain) : null; this.rootDn = (this.domain != null) ? rootDnFromDomain(this.domain) : null;
} }
@ -361,7 +362,7 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda
} }
String createBindPrincipal(String username) { String createBindPrincipal(String username) {
if (this.domain == null || username.toLowerCase().endsWith(this.domain)) { if (this.domain == null || username.toLowerCase(Locale.ROOT).endsWith(this.domain)) {
return username; return username;
} }
return username + "@" + this.domain; return username + "@" + this.domain;

View File

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
@ -179,7 +180,7 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
return null; return null;
} }
if (this.convertToUpperCase) { if (this.convertToUpperCase) {
role = role.toUpperCase(); role = role.toUpperCase(Locale.ROOT);
} }
return new SimpleGrantedAuthority(this.rolePrefix + role); return new SimpleGrantedAuthority(this.rolePrefix + role);
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Locale;
import javax.naming.Context; import javax.naming.Context;
import javax.naming.NameNotFoundException; import javax.naming.NameNotFoundException;
@ -120,7 +121,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
NamingEnumeration<?> ne = roleAttr.getAll(); NamingEnumeration<?> ne = roleAttr.getAll();
Object group = ne.next(); Object group = ne.next();
String role = group.toString(); String role = group.toString();
return new SimpleGrantedAuthority(this.rolePrefix + role.toUpperCase()); return new SimpleGrantedAuthority(this.rolePrefix + role.toUpperCase(Locale.ROOT));
}; };
private String[] attributesToRetrieve; private String[] attributesToRetrieve;
@ -283,7 +284,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
*/ */
protected DistinguishedName buildGroupDn(String group) { protected DistinguishedName buildGroupDn(String group) {
DistinguishedName dn = new DistinguishedName(this.groupSearchBase); DistinguishedName dn = new DistinguishedName(this.groupSearchBase);
dn.add(this.groupRoleAttributeName, group.toLowerCase()); dn.add(this.groupRoleAttributeName, group.toLowerCase(Locale.ROOT));
return dn; return dn;
} }

View File

@ -17,6 +17,7 @@
package org.springframework.security.ldap.userdetails; package org.springframework.security.ldap.userdetails;
import java.util.Collection; import java.util.Collection;
import java.util.Locale;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -127,7 +128,7 @@ public class LdapUserDetailsMapper implements UserDetailsContextMapper {
protected GrantedAuthority createAuthority(Object role) { protected GrantedAuthority createAuthority(Object role) {
if (role instanceof String) { if (role instanceof String) {
if (this.convertToUpperCase) { if (this.convertToUpperCase) {
role = ((String) role).toUpperCase(); role = ((String) role).toUpperCase(Locale.ROOT);
} }
return new SimpleGrantedAuthority(this.rolePrefix + role); return new SimpleGrantedAuthority(this.rolePrefix + role);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.security.ldap.userdetails;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -193,7 +194,7 @@ public class NestedLdapAuthoritiesPopulator extends DefaultLdapAuthoritiesPopula
} }
for (String role : roles) { for (String role : roles) {
if (isConvertToUpperCase()) { if (isConvertToUpperCase()) {
role = role.toUpperCase(); role = role.toUpperCase(Locale.ROOT);
} }
role = getRolePrefix() + role; role = getRolePrefix() + role;
// if the group already exist, we will not search for it's parents again. // if the group already exist, we will not search for it's parents again.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.security.oauth2.client.web.reactive.function.client;
import java.time.Duration; import java.time.Duration;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -749,7 +750,7 @@ public final class ServerOAuth2AuthorizedClientExchangeFilterFunction implements
// @formatter:off // @formatter:off
return Stream.of(wwwAuthenticateHeader) return Stream.of(wwwAuthenticateHeader)
.filter((header) -> !StringUtils.isEmpty(header)) .filter((header) -> !StringUtils.isEmpty(header))
.filter((header) -> header.toLowerCase().startsWith("bearer")) .filter((header) -> header.toLowerCase(Locale.ENGLISH).startsWith("bearer"))
.map((header) -> header.substring("bearer".length())) .map((header) -> header.substring("bearer".length()))
.map((header) -> header.split(",")) .map((header) -> header.split(","))
.flatMap(Stream::of) .flatMap(Stream::of)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.security.oauth2.client.web.reactive.function.client;
import java.time.Duration; import java.time.Duration;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -720,7 +721,7 @@ public final class ServletOAuth2AuthorizedClientExchangeFilterFunction implement
private Map<String, String> parseAuthParameters(String wwwAuthenticateHeader) { private Map<String, String> parseAuthParameters(String wwwAuthenticateHeader) {
// @formatter:off // @formatter:off
return Stream.of(wwwAuthenticateHeader).filter((header) -> !StringUtils.isEmpty(header)) return Stream.of(wwwAuthenticateHeader).filter((header) -> !StringUtils.isEmpty(header))
.filter((header) -> header.toLowerCase().startsWith("bearer")) .filter((header) -> header.toLowerCase(Locale.ENGLISH).startsWith("bearer"))
.map((header) -> header.substring("bearer".length())) .map((header) -> header.substring("bearer".length()))
.map((header) -> header.split(",")) .map((header) -> header.split(","))
.flatMap(Stream::of) .flatMap(Stream::of)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2010 the original author or authors. * Copyright 2004-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.security.taglibs.authz; package org.springframework.security.taglibs.authz;
import java.io.IOException; import java.io.IOException;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
@ -167,7 +168,7 @@ public abstract class AbstractAuthorizeTag {
} }
public void setMethod(String method) { public void setMethod(String method) {
this.method = (method != null) ? method.toUpperCase() : null; this.method = (method != null) ? method.toUpperCase(Locale.ENGLISH) : null;
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })

View File

@ -16,6 +16,8 @@
package org.springframework.security.web; package org.springframework.security.web;
import java.util.Locale;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -45,7 +47,7 @@ public class PortResolverImpl implements PortResolver {
@Override @Override
public int getServerPort(ServletRequest request) { public int getServerPort(ServletRequest request) {
int serverPort = request.getServerPort(); int serverPort = request.getServerPort();
String scheme = request.getScheme().toLowerCase(); String scheme = request.getScheme().toLowerCase(Locale.ENGLISH);
Integer mappedPort = getMappedPort(serverPort, scheme); Integer mappedPort = getMappedPort(serverPort, scheme);
return (mappedPort != null) ? mappedPort : serverPort; return (mappedPort != null) ? mappedPort : serverPort;
} }

View File

@ -16,6 +16,7 @@
package org.springframework.security.web.util; package org.springframework.security.web.util;
import java.util.Locale;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -49,7 +50,7 @@ public final class UrlUtils {
*/ */
public static String buildFullRequestUrl(String scheme, String serverName, int serverPort, String requestURI, public static String buildFullRequestUrl(String scheme, String serverName, int serverPort, String requestURI,
String queryString) { String queryString) {
scheme = scheme.toLowerCase(); scheme = scheme.toLowerCase(Locale.ENGLISH);
StringBuilder url = new StringBuilder(); StringBuilder url = new StringBuilder();
url.append(scheme).append("://").append(serverName); url.append(scheme).append("://").append(serverName);
// Only add port if not default // Only add port if not default

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.security.web.util.matcher; package org.springframework.security.web.util.matcher;
import java.util.Collections; import java.util.Collections;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -267,7 +268,7 @@ public final class AntPathRequestMatcher implements RequestMatcher, RequestVaria
private SubpathMatcher(String subpath, boolean caseSensitive) { private SubpathMatcher(String subpath, boolean caseSensitive) {
Assert.isTrue(!subpath.contains("*"), "subpath cannot contain \"*\""); Assert.isTrue(!subpath.contains("*"), "subpath cannot contain \"*\"");
this.subpath = caseSensitive ? subpath : subpath.toLowerCase(); this.subpath = caseSensitive ? subpath : subpath.toLowerCase(Locale.ROOT);
this.length = subpath.length(); this.length = subpath.length();
this.caseSensitive = caseSensitive; this.caseSensitive = caseSensitive;
} }
@ -275,7 +276,7 @@ public final class AntPathRequestMatcher implements RequestMatcher, RequestVaria
@Override @Override
public boolean matches(String path) { public boolean matches(String path) {
if (!this.caseSensitive) { if (!this.caseSensitive) {
path = path.toLowerCase(); path = path.toLowerCase(Locale.ROOT);
} }
return path.startsWith(this.subpath) && (path.length() == this.length || path.charAt(this.length) == '/'); return path.startsWith(this.subpath) && (path.length() == this.length || path.charAt(this.length) == '/');
} }