springsecurity中的自定义反序列化

1.实体类实现了Userdetails接口,重写了几个方法,但是admin实体类没有

Collection<? extends GrantedAuthority>这个属性,json就不能反序列化这个获得角色的类
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("t_admin")
@ApiModel(value="Admin对象", description="")
public class Admin implements Serializable, UserDetails {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "姓名")
    private String name;

    @ApiModelProperty(value = "手机号码")
    private String phone;

    @ApiModelProperty(value = "住宅电话")
    private String telephone;

    @ApiModelProperty(value = "联系地址")
    private String address;

    @ApiModelProperty(value = "是否启用")
    @Getter(AccessLevel.NONE)
    private Boolean enabled;

    @ApiModelProperty(value = "用户名")
    private String username;

    @ApiModelProperty(value = "密码")
    private String password;

    @ApiModelProperty(value = "用户头像")
    private String userFace;

    @ApiModelProperty(value = "备注")
    private String remark;

    @ApiModelProperty(value = "角色")
    @TableField(exist = false)
    private List<Role> roles;

    @Override
    @JsonDeserialize(using = CustomAuthorityDeserializer.class)
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<SimpleGrantedAuthority> authorities = roles
                .stream()
                .map(role -> new SimpleGrantedAuthority(role.getName()))
                .collect(Collectors.toList());
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }
}

2.场景:更新用户信息

这里从前端传入admin json对象,但是无法转换出Collection<? extends GrantedAuthority>类型的角色字段,所以必须使用自定义反序列化,转换出这个对象

@ApiOperation(value="更新当前用户信息")
@PutMapping("/admin/info")
public respBean updateAdmin(@RequestBody Admin admin,Authentication authentication){
if(adminService.updateById(admin)){
//将更新的对象使用security写到全局中去,表明当前的登录对象,以后可以使用principal 调用当前登录任
SecurityContextHolder.getContext().setAuthentication(new UserNamePasswordAuthenyicationToken(admin,null,authentication.getAuthorities));
return RespBean.success("更新成功");
}

}

3.编写反序列化类

public class CustomAuthorityDeserializer extends JsonDeserializer {
//json解析
	@Override
	public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
		ObjectMapper mapper = (ObjectMapper) p.getCodec(); 
		JsonNode jsonNode = mapper.readTree(p);//读取json数据
		List<GrantedAuthority> grantedAuthorities = new LinkedList<>();
		Iterator<JsonNode> elements = jsonNode.elements();//
		while (elements.hasNext()){
			JsonNode next = elements.next();
			JsonNode authority = next.get("authority");
			grantedAuthorities.add(new SimpleGrantedAuthority(authority.asText()));

		}
		return grantedAuthorities;
	}
}

4.在需要反序列化的类属性或方法上加上注释

    @JsonDeserialize(using = CustomAuthorityDeserializer.class)
上一篇:阿里云上数据统一备份 – 混合云备份服务解析


下一篇:Easy Excel动态组合导出