springboot~uaa~scope對實體的字段添加限制
scope授權思路
通過實現JsonSerializer抽象類的serialize方法來進行指定類型的序列化,在序列化中對持有ScopeSet注解的字段進行解析,當沒有對象的scope時,
對字段不進行渲染,從而保護了字段資源。
之前的嘗試MappingJackson2HttpMessageConverter
之前使用MappingJackson2HttpMessageConverter的定義,將@ScopeSet進行檢查,并對字段按著scope值進行輸出,最后的結果是失敗的,因為
MappingJackson2HttpMessageConverter只在程序啟動時執行一次,將類對應的字段添加到它的字典之后,如果下次有相同的實體字段,就不會去再執行
MappingJackson2HttpMessageConverter了,而我們要求的是每次序列化時都需要進行重新的解析,以查詢當前用戶的scope是否有對應的權限。
JsonSerializer的實現
接口在每次從服務端響應時都需要使用jackson的JsonSerializer功能,它有默認的實現方式,而我們可以重新去實現自己的方法,它在每次接口響應時都會被執行
ScopeSet
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ScopeSet {
/**
* 授權范圍.
*
* @return
*/
String value() default "";
}
在實體的和字段上添加scope

ScopeJsonSerializer序列化
@Slf4j
public class ScopeJsonSerializer<T> extends JsonSerializer<T> {
@SneakyThrows
@Override
public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
//引用類型
jsonGenerator.writeStartObject();
for (Field field : t.getClass().getDeclaredFields()) {
field.setAccessible(true);
if (field.getAnnotation(ScopeSet.class) != null) {
String value = field.getAnnotation(ScopeSet.class).value();
if (Arrays.asList(SecurityUser.getScope()).contains(value)) {
jsonGenerator.writeObjectField(field.getName(), field.get(t));
}
} else {
jsonGenerator.writeObjectField(field.getName(), field.get(t));
}
}
jsonGenerator.writeEndObject();
}
}
在DTO實體中使用,先在實體上聲明注解@JsonSerialize(using = ScopeJsonSerializer.class),之后在需要保護的字段上添加@ScopeSet注解即可。
當你的token.scope沒有read時,你的字段email將不會被輸出

感謝各位閱讀!
浙公網安備 33010602011771號