1 package org.oxerr.jackson.module.jsr250;
2
3 import java.io.IOException;
4 import java.io.ObjectInputStream;
5 import java.util.Collection;
6 import java.util.Collections;
7
8 import javax.annotation.security.DenyAll;
9 import javax.annotation.security.RolesAllowed;
10
11 import org.apache.logging.log4j.LogManager;
12 import org.apache.logging.log4j.Logger;
13 import org.springframework.security.core.Authentication;
14 import org.springframework.security.core.GrantedAuthority;
15 import org.springframework.security.core.context.SecurityContextHolder;
16
17 import com.fasterxml.jackson.core.JsonGenerationException;
18 import com.fasterxml.jackson.core.JsonGenerator;
19 import com.fasterxml.jackson.databind.JsonMappingException;
20 import com.fasterxml.jackson.databind.SerializerProvider;
21 import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
22 import com.fasterxml.jackson.databind.ser.BeanSerializer;
23
24
25
26
27
28 public class Jsr250JsonSerializer extends BeanSerializer {
29
30 private static final long serialVersionUID = 2016100501L;
31
32 private transient Logger log = LogManager.getLogger(Jsr250JsonSerializer.class);
33
34 public Jsr250JsonSerializer(BeanSerializer serializer) {
35 super(serializer);
36 }
37
38
39
40
41 @Override
42 protected void serializeFields(Object bean, JsonGenerator gen, SerializerProvider provider)
43 throws IOException, JsonGenerationException {
44 final Collection<? extends GrantedAuthority> grantedAuthorities = this
45 .getGrantedAuthorities();
46
47 final BeanPropertyWriter[] props;
48 if (_filteredProps != null && provider.getActiveView() != null) {
49 props = _filteredProps;
50 } else {
51 props = _props;
52 }
53 int i = 0;
54 try {
55 for (final int len = props.length; i < len; ++i) {
56 BeanPropertyWriter prop = props[i];
57 if (prop != null) {
58 final DenyAll denyAll = prop.getAnnotation(DenyAll.class);
59 final RolesAllowed rolesAllowed = prop.getAnnotation(RolesAllowed.class);
60 if (denyAll != null) {
61 log.trace("DenyAll, ignoring {}.", prop);
62 } else if (rolesAllowed != null && !this.isAllowed(rolesAllowed.value(), grantedAuthorities)) {
63 log.trace("RolesAllowed({}), ignoring {}.", rolesAllowed::value, () -> prop);
64 } else {
65 prop.serializeAsField(bean, gen, provider);
66 }
67 }
68 }
69 if (_anyGetterWriter != null) {
70 _anyGetterWriter.getAndSerialize(bean, gen, provider);
71 }
72 } catch (Exception e) {
73 String name = (i == props.length) ? "[anySetter]" : props[i].getName();
74 wrapAndThrow(provider, e, bean, name);
75 } catch (StackOverflowError e) {
76
77
78
79
80
81
82 JsonMappingException mapE = new JsonMappingException("Infinite recursion (StackOverflowError)", e);
83
84 String name = (i == props.length) ? "[anySetter]" : props[i].getName();
85 mapE.prependPath(new JsonMappingException.Reference(bean, name));
86 throw mapE;
87 }
88 }
89
90 protected boolean isAllowed(String[] rolesAllowed, Collection<? extends GrantedAuthority> grantedAuthorities) {
91 for (final String role : rolesAllowed) {
92 for (final GrantedAuthority grantedAuthority : grantedAuthorities) {
93 if (role.equals(grantedAuthority.getAuthority())) {
94 return true;
95 }
96 }
97 }
98 return false;
99 }
100
101 protected Collection<? extends GrantedAuthority> getGrantedAuthorities() {
102 final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
103 return authentication != null ? authentication.getAuthorities() : Collections.emptyList();
104 }
105
106 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
107 this.log = LogManager.getLogger(Jsr250JsonSerializer.class);
108 }
109
110 }