Fix UsernamePasswordAuthenticationTokenMixin to handle null credentials/details
Resolves #4698
This commit is contained in:
parent
82adf744f5
commit
881cd0befb
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package org.springframework.security.jackson2;
|
package org.springframework.security.jackson2;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
@ -24,12 +27,10 @@ import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.node.MissingNode;
|
import com.fasterxml.jackson.databind.node.MissingNode;
|
||||||
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom deserializer for {@link UsernamePasswordAuthenticationToken}. At the time of deserialization
|
* Custom deserializer for {@link UsernamePasswordAuthenticationToken}. At the time of deserialization
|
||||||
* it will invoke suitable constructor depending on the value of <b>authenticated</b> property.
|
* it will invoke suitable constructor depending on the value of <b>authenticated</b> property.
|
||||||
|
@ -39,6 +40,7 @@ import java.util.List;
|
||||||
* you can also registered it with your own mixin class.
|
* you can also registered it with your own mixin class.
|
||||||
*
|
*
|
||||||
* @author Jitendra Singh
|
* @author Jitendra Singh
|
||||||
|
* @author Greg Turnquist
|
||||||
* @see UsernamePasswordAuthenticationTokenMixin
|
* @see UsernamePasswordAuthenticationTokenMixin
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +67,13 @@ class UsernamePasswordAuthenticationTokenDeserializer extends JsonDeserializer<U
|
||||||
} else {
|
} else {
|
||||||
principal = principalNode.asText();
|
principal = principalNode.asText();
|
||||||
}
|
}
|
||||||
Object credentials = readJsonNode(jsonNode, "credentials").asText();
|
JsonNode credentialsNode = readJsonNode(jsonNode, "credentials");
|
||||||
|
Object credentials;
|
||||||
|
if (credentialsNode.isNull()) {
|
||||||
|
credentials = null;
|
||||||
|
} else {
|
||||||
|
credentials = credentialsNode.asText();
|
||||||
|
}
|
||||||
List<GrantedAuthority> authorities = mapper.readValue(
|
List<GrantedAuthority> authorities = mapper.readValue(
|
||||||
readJsonNode(jsonNode, "authorities").traverse(mapper), new TypeReference<List<GrantedAuthority>>() {
|
readJsonNode(jsonNode, "authorities").traverse(mapper), new TypeReference<List<GrantedAuthority>>() {
|
||||||
});
|
});
|
||||||
|
@ -74,7 +82,12 @@ class UsernamePasswordAuthenticationTokenDeserializer extends JsonDeserializer<U
|
||||||
} else {
|
} else {
|
||||||
token = new UsernamePasswordAuthenticationToken(principal, credentials);
|
token = new UsernamePasswordAuthenticationToken(principal, credentials);
|
||||||
}
|
}
|
||||||
token.setDetails(readJsonNode(jsonNode, "details"));
|
JsonNode detailsNode = readJsonNode(jsonNode, "details");
|
||||||
|
if (detailsNode.isNull()) {
|
||||||
|
token.setDetails(null);
|
||||||
|
} else {
|
||||||
|
token.setDetails(detailsNode);
|
||||||
|
}
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,11 @@ import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jitendra Singh
|
* @author Jitendra Singh
|
||||||
|
* @author Greg Turnquist
|
||||||
* @since 4.2
|
* @since 4.2
|
||||||
*/
|
*/
|
||||||
public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixinTests {
|
public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixinTests {
|
||||||
|
@ -150,6 +151,20 @@ public class UsernamePasswordAuthenticationTokenMixinTests extends AbstractMixin
|
||||||
assertThat(token.getPrincipal()).isNotNull().isInstanceOf(NonUserPrincipal.class);
|
assertThat(token.getPrincipal()).isNotNull().isInstanceOf(NonUserPrincipal.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serializingThenDeserializingWithNoCredentialsOrDetailsShouldWork() throws IOException {
|
||||||
|
// given
|
||||||
|
UsernamePasswordAuthenticationToken original = new UsernamePasswordAuthenticationToken("Frodo", null);
|
||||||
|
|
||||||
|
// when
|
||||||
|
String serialized = this.mapper.writeValueAsString(original);
|
||||||
|
UsernamePasswordAuthenticationToken deserialized = this.mapper.readValue(serialized, UsernamePasswordAuthenticationToken.class);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(deserialized).isEqualTo(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private UsernamePasswordAuthenticationToken createToken() {
|
private UsernamePasswordAuthenticationToken createToken() {
|
||||||
User user = createDefaultUser();
|
User user = createDefaultUser();
|
||||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
|
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
|
||||||
|
|
Loading…
Reference in New Issue