Skip to content

Commit

Permalink
Merge branch 'spring-projects:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
irerin07 authored Jan 31, 2024
2 parents d42da04 + c1adeef commit 64d5ab5
Show file tree
Hide file tree
Showing 43 changed files with 2,063 additions and 102 deletions.
9 changes: 9 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ updates:
- dependency-name: "*"
update-types: [ "version-update:semver-major", "version-update:semver-minor" ]

- package-ecosystem: "gradle"
target-branch: "docs-build"
directory: "/"
schedule:
interval: "daily"
time: "03:00"
timezone: "Etc/UTC"
labels: [ "type: dependency-upgrade" ]

# GitHub Actions

- package-ecosystem: github-actions
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/continuous-integration-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ jobs:
distribution: 'temurin'
cache: 'gradle'
- name: Set up Gradle
uses: gradle/gradle-build-action@v2
uses: gradle/gradle-build-action@v3
- name: Set up gradle user name
run: echo 'systemProp.user.name=spring-builds+github' >> gradle.properties
- name: Build with Gradle
Expand Down Expand Up @@ -254,7 +254,7 @@ jobs:
./gradlew createGitHubRelease -PnextVersion=$VERSION -Pbranch=$BRANCH -PcreateRelease=true -PgitHubAccessToken=$TOKEN
- name: Announce Release on Slack
id: spring-security-announcing
uses: slackapi/slack-github-action@v1.24.0
uses: slackapi/slack-github-action@v1.25.0
with:
payload: |
{
Expand Down
55 changes: 55 additions & 0 deletions .github/workflows/edit-dependabot-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This workflow is an adaptation from https://github.com/spring-projects/spring-integration/blob/main/.github/workflows/merge-dependabot-pr.yml
# and https://github.com/spring-io/spring-github-workflows/blob/main/.github/workflows/spring-merge-dependabot-pr.yml

name: Edit Dependabot PR

on:
pull_request:

run-name: Edit Dependabot PR ${{ github.ref_name }}

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
edit-dependabot-pr:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
permissions: write-all
steps:

- uses: actions/checkout@v4
with:
show-progress: false

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17

- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v1
with:
github-token: ${{ env.GH_TOKEN }}

- name: Set Milestone to Dependabot pull request
id: set-milestone
run: |
if test -f pom.xml
then
CURRENT_VERSION=$(mvn help:evaluate -Dexpression="project.version" -q -DforceStdout)
else
CURRENT_VERSION=$(cat gradle.properties | sed -n '/^version=/ { s/^version=//;p }')
fi
export CANDIDATE_VERSION=${CURRENT_VERSION/-SNAPSHOT}
MILESTONE=$(gh api repos/$GITHUB_REPOSITORY/milestones --jq 'map(select(.due_on != null and (.title | startswith(env.CANDIDATE_VERSION)))) | .[0] | .title')
if [ -z $MILESTONE ]
then
gh run cancel ${{ github.run_id }}
echo "::warning title=Cannot merge::No scheduled milestone for $CURRENT_VERSION version"
else
gh pr edit ${{ github.event.pull_request.number }} --milestone $MILESTONE
echo mergeEnabled=true >> $GITHUB_OUTPUT
fi
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ image::https://badges.gitter.im/Join%20Chat.svg[Gitter,link=https://gitter.im/sp

image:https://github.com/spring-projects/spring-security/actions/workflows/continuous-integration-workflow.yml/badge.svg?branch=main["Build Status", link="https://github.com/spring-projects/spring-security/actions/workflows/continuous-integration-workflow.yml"]

image:https://img.shields.io/badge/Revved%20up%20by-Gradle%20Enterprise-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Gradle Enterprise", link="https://ge.spring.io/scans?search.rootProjectNames=spring-security"]
image:https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A["Revved up by Develocity", link="https://ge.spring.io/scans?search.rootProjectNames=spring-security"]

= Spring Security

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,14 @@ public Mono<Authentication> authenticate(Authentication authentication) throws A

private Mono<Jwt> decode(ClientRegistration registration, String token) {
ReactiveJwtDecoder logoutTokenDecoder = this.logoutTokenDecoderFactory.createDecoder(registration);
try {
return logoutTokenDecoder.decode(token);
}
catch (BadJwtException failed) {
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST, failed.getMessage(),
"https://openid.net/specs/openid-connect-backchannel-1_0.html#Validation");
return Mono.error(new OAuth2AuthenticationException(error, failed));
}
catch (Exception failed) {
return Mono.error(new AuthenticationServiceException(failed.getMessage(), failed));
}
return logoutTokenDecoder.decode(token).onErrorResume(Exception.class, (ex) -> {
if (ex instanceof BadJwtException) {
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST, ex.getMessage(),
"https://openid.net/specs/openid-connect-backchannel-1_0.html#Validation");
return Mono.error(new OAuth2AuthenticationException(error, ex));
}
return Mono.error(new AuthenticationServiceException(ex.getMessage(), ex));
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
Expand Down Expand Up @@ -38,6 +38,8 @@ import jakarta.servlet.http.HttpServletRequest
* @property loginProcessingUrl the URL to validate the credentials
* @property permitAll whether to grant access to the urls for [failureUrl] as well as
* for the [HttpSecurityBuilder], the [loginPage] and [loginProcessingUrl] for every user
* @property usernameParameter the HTTP parameter to look for the username when performing authentication
* @property passwordParameter the HTTP parameter to look for the password when performing authentication
*/
@SecurityMarker
class FormLoginDsl {
Expand All @@ -48,6 +50,8 @@ class FormLoginDsl {
var loginProcessingUrl: String? = null
var permitAll: Boolean? = null
var authenticationDetailsSource: AuthenticationDetailsSource<HttpServletRequest, *>? = null
var usernameParameter: String? = null
var passwordParameter: String? = null

private var defaultSuccessUrlOption: Pair<String, Boolean>? = null

Expand Down Expand Up @@ -95,6 +99,8 @@ class FormLoginDsl {
authenticationSuccessHandler?.also { login.successHandler(authenticationSuccessHandler) }
authenticationFailureHandler?.also { login.failureHandler(authenticationFailureHandler) }
authenticationDetailsSource?.also { login.authenticationDetailsSource(authenticationDetailsSource) }
usernameParameter?.also { login.usernameParameter(usernameParameter) }
passwordParameter?.also { login.passwordParameter(passwordParameter) }
if (disabled) {
login.disable()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
Expand Down Expand Up @@ -33,6 +33,7 @@ import org.springframework.security.config.test.SpringTestContextExtension
import org.springframework.security.core.userdetails.User
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf
import org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler
Expand Down Expand Up @@ -367,6 +368,50 @@ class FormLoginDslTests {
verify(exactly = 1) { CustomAuthenticationDetailsSourceConfig.AUTHENTICATION_DETAILS_SOURCE.buildDetails(any()) }
}

@Configuration
@EnableWebSecurity
open class CustomUsernameParameterConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
formLogin {
usernameParameter = "custom-username"
}
}
return http.build()
}
}

@Test
fun `form login when custom username parameter then used`() {
this.spring.register(CustomUsernameParameterConfig::class.java, UserConfig::class.java).autowire()

this.mockMvc.perform(formLogin().userParameter("custom-username"))
.andExpect(authenticated())
}

@Configuration
@EnableWebSecurity
open class CustomPasswordParameterConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
formLogin {
passwordParameter = "custom-password"
}
}
return http.build()
}
}

@Test
fun `form login when custom password parameter then used`() {
this.spring.register(CustomPasswordParameterConfig::class.java, UserConfig::class.java).autowire()

this.mockMvc.perform(formLogin().passwordParam("custom-password"))
.andExpect(authenticated())
}

@Configuration
@EnableWebSecurity
open class CustomAuthenticationDetailsSourceConfig {
Expand Down
3 changes: 2 additions & 1 deletion crypto/spring-security-crypto.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ apply plugin: 'io.spring.convention.spring-module'
dependencies {
management platform(project(":spring-security-dependencies"))
optional 'org.springframework:spring-jcl'
optional 'org.springframework:spring-core'
optional 'org.bouncycastle:bcpkix-jdk15on'

testImplementation "org.assertj:assertj-core"
testImplementation "org.junit.jupiter:junit-jupiter-api"
testImplementation "org.junit.jupiter:junit-jupiter-params"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright 2013-2024 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.crypto.encrypt;

import java.io.InputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.RSAPublicKeySpec;

import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;

/**
* @author Dave Syer
* @author Tim Ysewyn
* @since 6.3
*/
public class KeyStoreKeyFactory {

private final Resource resource;

private final char[] password;

private KeyStore store;

private final Object lock = new Object();

private final String type;

public KeyStoreKeyFactory(Resource resource, char[] password) {
this(resource, password, type(resource));
}

private static String type(Resource resource) {
String ext = StringUtils.getFilenameExtension(resource.getFilename());
return (ext != null) ? ext : "jks";
}

public KeyStoreKeyFactory(Resource resource, char[] password, String type) {
this.resource = resource;
this.password = password;
this.type = type;
}

public KeyPair getKeyPair(String alias) {
return getKeyPair(alias, this.password);
}

public KeyPair getKeyPair(String alias, char[] password) {
try {
synchronized (this.lock) {
if (this.store == null) {
synchronized (this.lock) {
this.store = KeyStore.getInstance(this.type);
try (InputStream stream = this.resource.getInputStream()) {
this.store.load(stream, this.password);
}
}
}
}
RSAPrivateCrtKey key = (RSAPrivateCrtKey) this.store.getKey(alias, password);
Certificate certificate = this.store.getCertificate(alias);
PublicKey publicKey = null;
if (certificate != null) {
publicKey = certificate.getPublicKey();
}
else if (key != null) {
RSAPublicKeySpec spec = new RSAPublicKeySpec(key.getModulus(), key.getPublicExponent());
publicKey = KeyFactory.getInstance("RSA").generatePublic(spec);
}
return new KeyPair(publicKey, key);
}
catch (Exception ex) {
throw new IllegalStateException("Cannot load keys from store: " + this.resource, ex);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2013-2024 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.crypto.encrypt;

/**
* @author Dave Syer
* @since 6.3
*/
public enum RsaAlgorithm {

DEFAULT("RSA", 117), OAEP("RSA/ECB/OAEPPadding", 86);

private final String name;

private final int maxLength;

RsaAlgorithm(String name, int maxLength) {
this.name = name;
this.maxLength = maxLength;
}

public String getJceName() {
return this.name;
}

public int getMaxLength() {
return this.maxLength;
}

}
Loading

0 comments on commit 64d5ab5

Please sign in to comment.