Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExclusionStrategy cannot depend on threadlocal #2205

Closed
jandm123 opened this issue Sep 27, 2022 · 2 comments · Fixed by #2215
Closed

ExclusionStrategy cannot depend on threadlocal #2205

jandm123 opened this issue Sep 27, 2022 · 2 comments · Fixed by #2215

Comments

@jandm123
Copy link

In a Spring environment (or equivalent), it is common practice to implement security by checking on the current security context, which is a threadlocal object. Gson exclusion strategies are only evaluated once, it seems. I understand this is a performance concern, but would appreciate if this could be made configurable. At the minimum a warning could be placed on the ExclusionStrategy interface.

@Marcono1234
Copy link
Collaborator

Is this about field or type exclusions?

  • For field exclusions (and exclusions for field types), the internal ReflectiveTypeAdapterFactory.getBoundFields method considers these exclusions once when the reflection-based adapter is created.
  • For type exclusions, the internal Excluder class acts as a TypeAdapterFactory which creates a type adapter which ignores the class.

In both cases, once Gson has cached the adapter in the typeTokenCache it will not be created again. I am not sure if changing this implementation is worth it.

As workaround for the type exclusions you could probably write a custom TypeAdapterFactory which creates a TypeAdapter which checks your ThreadLocal object before delegating to the actual adapter.

Out of curiosity, could you share a bit more information about how exactly you are using the ThreadLocal with the exclusion strategy?

@jandm123
Copy link
Author

jandm123 commented Sep 29, 2022

Thanks for the explanation, @Marcono1234 , this confirms my findings so far.

To illustrate my problem, suppose i would like to expose certain DTO fields based on whether the user is authenticated or not.
A very simple exclusion strategy might be to evaluate the authenticated state at serialization time.

  • Introduce an annotation NeedsAuthentication:

`public class MyDto {

@NeedsAuthentication
private String secret;

}`

  • Evaluate the authentication state at serialization time:

`public class AuthenticationBasedFieldExclusionStrategy implements ExclusionStrategy {

@Override
public boolean shouldSkipField(FieldAttributes field) {
	NeedsAuthentication annotation = field.getAnnotation(NeedsAuthentication.class);
	if (annotation == null) {
		return false;
	} else {
		// this hits a threadlocal !
		return !SecurityContextHolder.getContext().getAuthentication().isAuthenticated();
	}
}

@Override
public boolean shouldSkipClass(Class<?> clazz) {
	return false;
}

}
`
As you can see this wont work with the current implementation. I could indeed create my custom TypeAdapterFactory but i was hoping there is a shorter way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants