# How to Implement Sensitive Data Masking in ContiNew Admin: A Complete Guide

> Learn how to implement sensitive data masking in ContiNew Admin using the continew starter security mask. Automatically desensitize data with JsonMask annotation for secure JSON serialization.

- Repository: [OpenContiNew/continew-admin](https://github.com/continew-org/continew-admin)
- Tags: how-to-guide
- Published: 2026-02-28

---

**ContiNew Admin provides built-in sensitive data masking through the `continew-starter-security-mask` starter, which automatically desensitizes fields annotated with `@JsonMask` during Jackson JSON serialization.**

ContiNew Admin is a modern Java admin template built on Spring Boot that prioritizes security by design. To help developers implement sensitive data masking without boilerplate code, the framework ships with `continew-starter-security-mask`, a lightweight starter that integrates seamlessly with Jackson to mask sensitive fields before they leave the server.

## How the Masking System Works

The desensitization mechanism operates at the serialization layer through three core components provided by the starter library.

**Jackson Integration.** The starter registers a custom serializer (`top.continew.starter.security.mask.jackson.JsonMaskSerializer`) that intercepts the JSON conversion process. When Spring MVC converts response objects to JSON via `MappingJackson2HttpMessageConverter`, this serializer examines fields for the `@JsonMask` annotation.

**Annotation-Driven Configuration.** Developers apply `top.continew.starter.security.mask.annotation.JsonMask` to any DTO field requiring protection. The annotation accepts either a preset mask type from `top.continew.starter.security.mask.enums.MaskType` or custom character retention settings.

**Zero Runtime Overhead.** Because masking occurs during the final JSON serialization step, raw sensitive values never appear in HTTP responses, application logs, or client-side payloads.

## Prerequisites and Configuration

Before implementing masking, verify that your project includes the security mask starter dependency.

In [`continew-common/pom.xml`](https://github.com/continew-org/continew-admin/blob/main/continew-common/pom.xml), the dependency is declared as:

```xml
<dependency>
    <groupId>top.continew</groupId>
    <artifactId>continew-starter-security-mask</artifactId>
</dependency>

```

No additional Java configuration or bean registration is required. Once the dependency is present on the classpath, the Jackson serializer auto-registers and activates for all response DTOs.

## Implementing Masking in Response DTOs

Apply the `@JsonMask` annotation to String fields in your response classes. The starter supports two masking strategies: preset patterns for common data types and custom character-based masking for specialized requirements.

### Using Preset Mask Types

The `MaskType` enum provides standardized masking rules for frequently handled sensitive data. Available presets include:

- `EMAIL` – Masks the local-part of email addresses (e.g., `user@example.com` → `u***@example.com`)
- `MOBILE_PHONE` – Masks the middle digits of Chinese mobile numbers (e.g., `13800138000` → `138****8000`)

In [`continew-system/src/main/java/top/continew/admin/system/model/resp/user/UserResp.java`](https://github.com/continew-org/continew-admin/blob/main/continew-system/src/main/java/top/continew/admin/system/model/resp/user/UserResp.java), email and phone fields are protected using preset types:

```java
import top.continew.starter.security.mask.annotation.JsonMask;
import top.continew.starter.security.mask.enums.MaskType;

public class UserResp {
    
    private Long id;
    private String username;
    
    @JsonMask(MaskType.EMAIL)
    private String email;
    
    @JsonMask(MaskType.MOBILE_PHONE)
    private String mobile;
    
    // getters and setters
}

```

### Creating Custom Mask Patterns

For data types not covered by presets, specify `left` and `right` integer parameters to define how many characters remain visible at the start and end of the string. The middle portion is replaced with asterisks.

In [`continew-system/src/main/java/top/continew/admin/system/model/resp/SmsConfigResp.java`](https://github.com/continew-org/continew-admin/blob/main/continew-system/src/main/java/top/continew/admin/system/model/resp/SmsConfigResp.java), the access key uses custom masking to show only the first and last four characters:

```java
public class SmsConfigResp {
    
    private Long id;
    private String provider;
    
    @JsonMask(left = 4, right = 4)
    private String accessKey;
    
    // getters and setters
}

```

This configuration transforms `1234567890123456` into `1234********3456` in the JSON output.

## Real-World Code Examples

The following implementations demonstrate how ContiNew Admin handles sensitive data masking in production endpoints.

### Masking User Contact Information

The `UserResp` class in the system module protects personally identifiable information using preset masks. When the `UserController` returns this DTO, clients receive automatically redacted data:

```java
@RestController
@RequestMapping("/api/system/users")
public class UserController {
    
    @GetMapping("/{id}")
    public UserResp getUser(@PathVariable Long id) {
        UserResp user = userService.getUserRespById(id);
        // Raw email and mobile values exist in memory only
        // JSON response contains masked versions automatically
        return user;
    }
}

```

### Custom Masking for API Credentials

Third-party integration credentials require specialized masking patterns. The `SmsConfigResp` example shows how to protect API keys while maintaining enough visible characters for identification:

```java
@JsonMask(left = 4, right = 4)
private String accessKeyId;

@JsonMask(left = 0, right = 4)
private String accessKeySecret;

```

Setting `left = 0` masks the entire string except the last four characters, suitable for secret keys where only the suffix is needed for verification.

### Authentication Response Handling

The `UserInfoResp` class in [`continew-system/src/main/java/top/continew/admin/auth/model/resp/UserInfoResp.java`](https://github.com/continew-org/continew-admin/blob/main/continew-system/src/main/java/top/continew/admin/auth/model/resp/UserInfoResp.java) demonstrates masking in authentication contexts, ensuring that sensitive user attributes remain protected even in login response payloads.

## Summary

- **Add the starter**: Include `continew-starter-security-mask` in [`continew-common/pom.xml`](https://github.com/continew-org/continew-admin/blob/main/continew-common/pom.xml) to enable automatic masking capabilities.
- **Annotate fields**: Apply `@JsonMask` with either `MaskType` presets or custom `left`/`right` values to any String field requiring protection.
- **Zero configuration**: The Jackson serializer auto-registers and processes masking during JSON conversion without controller modifications.
- **Security by default**: Raw values never serialize to HTTP responses, eliminating accidental data leakage through API endpoints or logs.

## Frequently Asked Questions

### How do I mask a credit card number to show only the last four digits?

Use the custom masking parameters with `left = 0` and `right = 4`. This configuration preserves only the final four characters while replacing the rest with asterisks: `@JsonMask(left = 0, right = 4) private String cardNumber;`.

### Does the masking affect the original object values in memory?

No. The `JsonMaskSerializer` operates during the final JSON serialization phase. The original DTO fields retain their complete values within the JVM; only the HTTP response payload contains the masked representation.

### Can I create custom MaskType presets for my organization?

The current implementation in `continew-starter-security-mask` provides standard presets through the `MaskType` enum. For organization-specific patterns, use the `left` and `right` parameters in the annotation, or extend the starter's serializer logic to register additional enum values.

### Where is the masking logic physically located in the source code?

While the `@JsonMask` annotation, `MaskType` enum, and `JsonMaskSerializer` reside in the external starter library (`top.continew.starter.security.mask`), you can observe their practical application in the following ContiNew Admin files:
- [`continew-system/src/main/java/top/continew/admin/system/model/resp/user/UserResp.java`](https://github.com/continew-org/continew-admin/blob/main/continew-system/src/main/java/top/continew/admin/system/model/resp/user/UserResp.java)
- [`continew-system/src/main/java/top/continew/admin/system/model/resp/SmsConfigResp.java`](https://github.com/continew-org/continew-admin/blob/main/continew-system/src/main/java/top/continew/admin/system/model/resp/SmsConfigResp.java)
- [`continew-system/src/main/java/top/continew/admin/auth/model/resp/UserInfoResp.java`](https://github.com/continew-org/continew-admin/blob/main/continew-system/src/main/java/top/continew/admin/auth/model/resp/UserInfoResp.java)