forked from spring-projects/spring-security
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for automatic context-propagation with Micrometer
Closes spring-projectsgh-16665
- Loading branch information
Showing
9 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
...ringframework/security/core/context/ReactiveSecurityContextHolderThreadLocalAccessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright 2002-2025 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.core.context; | ||
|
||
import io.micrometer.context.ThreadLocalAccessor; | ||
import reactor.core.publisher.Mono; | ||
|
||
import org.springframework.util.Assert; | ||
|
||
/** | ||
* A {@link ThreadLocalAccessor} for accessing a {@link SecurityContext} with the | ||
* {@link ReactiveSecurityContextHolder}. | ||
* <p> | ||
* This class adapts the {@link ReactiveSecurityContextHolder} to the | ||
* {@link ThreadLocalAccessor} contract to allow Micrometer Context Propagation to | ||
* automatically propagate a {@link SecurityContext} in Reactive applications. It is | ||
* automatically registered with the {@link io.micrometer.context.ContextRegistry} through | ||
* the {@link java.util.ServiceLoader} mechanism when context-propagation is on the | ||
* classpath. | ||
* | ||
* @author Steve Riesenberg | ||
* @since 6.5 | ||
* @see io.micrometer.context.ContextRegistry | ||
*/ | ||
public final class ReactiveSecurityContextHolderThreadLocalAccessor | ||
implements ThreadLocalAccessor<Mono<SecurityContext>> { | ||
|
||
private static final ThreadLocal<Mono<SecurityContext>> threadLocal = new ThreadLocal<>(); | ||
|
||
@Override | ||
public Object key() { | ||
return SecurityContext.class; | ||
} | ||
|
||
@Override | ||
public Mono<SecurityContext> getValue() { | ||
return threadLocal.get(); | ||
} | ||
|
||
@Override | ||
public void setValue(Mono<SecurityContext> securityContext) { | ||
Assert.notNull(securityContext, "securityContext cannot be null"); | ||
threadLocal.set(securityContext); | ||
} | ||
|
||
@Override | ||
public void setValue() { | ||
threadLocal.remove(); | ||
} | ||
|
||
} |
60 changes: 60 additions & 0 deletions
60
...a/org/springframework/security/core/context/SecurityContextHolderThreadLocalAccessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright 2002-2025 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.core.context; | ||
|
||
import io.micrometer.context.ThreadLocalAccessor; | ||
|
||
/** | ||
* A {@link ThreadLocalAccessor} for accessing a {@link SecurityContext} with the | ||
* {@link SecurityContextHolder}. | ||
* <p> | ||
* This class adapts the {@link SecurityContextHolder} to the {@link ThreadLocalAccessor} | ||
* contract to allow Micrometer Context Propagation to automatically propagate a | ||
* {@link SecurityContext} in Servlet applications. It is automatically registered with | ||
* the {@link io.micrometer.context.ContextRegistry} through the | ||
* {@link java.util.ServiceLoader} mechanism when context-propagation is on the classpath. | ||
* | ||
* @author Steve Riesenberg | ||
* @since 6.5 | ||
* @see io.micrometer.context.ContextRegistry | ||
*/ | ||
public final class SecurityContextHolderThreadLocalAccessor implements ThreadLocalAccessor<SecurityContext> { | ||
|
||
@Override | ||
public Object key() { | ||
return SecurityContext.class.getName(); | ||
} | ||
|
||
@Override | ||
public SecurityContext getValue() { | ||
SecurityContext securityContext = SecurityContextHolder.getContext(); | ||
SecurityContext emptyContext = SecurityContextHolder.createEmptyContext(); | ||
|
||
return !securityContext.equals(emptyContext) ? securityContext : null; | ||
} | ||
|
||
@Override | ||
public void setValue(SecurityContext value) { | ||
SecurityContextHolder.setContext(value); | ||
} | ||
|
||
@Override | ||
public void setValue() { | ||
SecurityContextHolder.clearContext(); | ||
} | ||
|
||
} |
2 changes: 2 additions & 0 deletions
2
core/src/main/resources/META-INF/spring/io.micrometer.context.ThreadLocalAccessor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
org.springframework.security.core.context.ReactiveSecurityContextHolderThreadLocalAccessor | ||
org.springframework.security.core.context.SecurityContextHolderThreadLocalAccessor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
...in/java/org/springframework/security/web/server/ServerWebExchangeThreadLocalAccessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* | ||
* Copyright 2002-2025 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.web.server; | ||
|
||
import io.micrometer.context.ThreadLocalAccessor; | ||
|
||
import org.springframework.util.Assert; | ||
import org.springframework.web.server.ServerWebExchange; | ||
|
||
/** | ||
* A {@link ThreadLocalAccessor} for accessing a {@link ServerWebExchange}. | ||
* <p> | ||
* This class adapts the existing Reactor Context attribute | ||
* {@code ServerWebExchange.class} to the {@link ThreadLocalAccessor} contract to allow | ||
* Micrometer Context Propagation to automatically propagate a {@link ServerWebExchange} | ||
* in Reactive applications. It is automatically registered with the | ||
* {@link io.micrometer.context.ContextRegistry} through the | ||
* {@link java.util.ServiceLoader} mechanism when context-propagation is on the classpath. | ||
* | ||
* @author Steve Riesenberg | ||
* @since 6.5 | ||
* @see io.micrometer.context.ContextRegistry | ||
*/ | ||
public final class ServerWebExchangeThreadLocalAccessor implements ThreadLocalAccessor<ServerWebExchange> { | ||
|
||
private static final ThreadLocal<ServerWebExchange> threadLocal = new ThreadLocal<>(); | ||
|
||
@Override | ||
public Object key() { | ||
return ServerWebExchange.class; | ||
} | ||
|
||
@Override | ||
public ServerWebExchange getValue() { | ||
return threadLocal.get(); | ||
} | ||
|
||
@Override | ||
public void setValue(ServerWebExchange exchange) { | ||
Assert.notNull(exchange, "exchange must not be null"); | ||
threadLocal.set(exchange); | ||
} | ||
|
||
@Override | ||
public void setValue() { | ||
threadLocal.remove(); | ||
} | ||
|
||
} |
1 change: 1 addition & 0 deletions
1
web/src/main/resources/META-INF/spring/io.micrometer.context.ThreadLocalAccessor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
org.springframework.security.web.server.ServerWebExchangeThreadLocalAccessor |