@ -18,6 +18,8 @@ package org.springframework.security.oauth2.server.resource.web.authentication;
@@ -18,6 +18,8 @@ package org.springframework.security.oauth2.server.resource.web.authentication;
import java.io.IOException ;
import java.util.Map ;
import java.util.Set ;
import java.util.stream.Collectors ;
import jakarta.servlet.FilterChain ;
import jakarta.servlet.ServletException ;
@ -30,6 +32,7 @@ import org.springframework.security.authentication.AuthenticationManager;
@@ -30,6 +32,7 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationManagerResolver ;
import org.springframework.security.core.Authentication ;
import org.springframework.security.core.AuthenticationException ;
import org.springframework.security.core.GrantedAuthority ;
import org.springframework.security.core.context.SecurityContext ;
import org.springframework.security.core.context.SecurityContextHolder ;
import org.springframework.security.core.context.SecurityContextHolderStrategy ;
@ -53,6 +56,7 @@ import org.springframework.security.web.context.RequestAttributeSecurityContextR
@@ -53,6 +56,7 @@ import org.springframework.security.web.context.RequestAttributeSecurityContextR
import org.springframework.security.web.context.SecurityContextRepository ;
import org.springframework.util.Assert ;
import org.springframework.util.CollectionUtils ;
import org.springframework.util.ReflectionUtils ;
import org.springframework.util.StringUtils ;
import org.springframework.web.filter.OncePerRequestFilter ;
@ -181,10 +185,17 @@ public class BearerTokenAuthenticationFilter extends OncePerRequestFilter {
@@ -181,10 +185,17 @@ public class BearerTokenAuthenticationFilter extends OncePerRequestFilter {
throw new OAuth2AuthenticationException ( error ) ;
}
Authentication current = this . securityContextHolderStrategy . getContext ( ) . getAuthentication ( ) ;
if ( current ! = null & & current . isAuthenticated ( ) ) {
authenticationResult = authenticationResult . toBuilder ( )
. authorities ( ( a ) - > a . addAll ( current . getAuthorities ( ) ) )
. build ( ) ;
if ( current ! = null & & current . isAuthenticated ( ) & & declaresToBuilder ( authenticationResult ) ) {
authenticationResult = authenticationResult . toBuilder ( ) . authorities ( ( a ) - > {
Set < String > newAuthorities = a . stream ( )
. map ( GrantedAuthority : : getAuthority )
. collect ( Collectors . toUnmodifiableSet ( ) ) ;
for ( GrantedAuthority currentAuthority : current . getAuthorities ( ) ) {
if ( ! newAuthorities . contains ( currentAuthority . getAuthority ( ) ) ) {
a . add ( currentAuthority ) ;
}
}
} ) . build ( ) ;
}
SecurityContext context = this . securityContextHolderStrategy . createEmptyContext ( ) ;
context . setAuthentication ( authenticationResult ) ;
@ -202,6 +213,10 @@ public class BearerTokenAuthenticationFilter extends OncePerRequestFilter {
@@ -202,6 +213,10 @@ public class BearerTokenAuthenticationFilter extends OncePerRequestFilter {
}
}
private static boolean declaresToBuilder ( Authentication authentication ) {
return ReflectionUtils . findMethod ( authentication . getClass ( ) , "toBuilder" ) ! = null ;
}
/ * *
* Sets the { @link SecurityContextHolderStrategy } to use . The default action is to use
* the { @link SecurityContextHolderStrategy } stored in { @link SecurityContextHolder } .