Overview
The User Management System uses a simple but effective role-based access control model with two distinct roles. Each role has specific permissions that determine what actions users can perform and which endpoints they can access.Available Roles
Roles are defined as an enum inRole.java:3-6:
Using an enum ensures type safety and prevents invalid role assignments. The role is stored as a string in the database using JPA’s
@Enumerated(EnumType.STRING) annotation.ROLE_USER
Description: Standard user role with basic access permissions. Assigned to: All newly registered users by default. Capabilities:- View their own user information
- Update their own profile (future functionality)
- Access user-level endpoints
- Cannot view other users
- Cannot access administrative functions
- Cannot modify system settings
ROLE_ADMIN
Description: Administrator role with elevated privileges. Assigned to: System administrators (manual assignment required). Capabilities:- View all users in the system
- Access administrative endpoints
- Perform system-wide operations
- All permissions that ROLE_USER has (in most implementations)
- Must be explicitly assigned (not available through signup)
Default Role Assignment
When a new user registers, they are automatically assigned theROLE_USER role. This is implemented using Lombok’s @Builder.Default annotation in User.java:32-33:
Registration Flow
The default role assignment happens automatically during user creation. There is no need to specify a role when signing up—all new users start as
ROLE_USER.Role Storage
Roles are stored in the database as part of the User entity:- Database Column:
role(VARCHAR type) - Format: String representation (e.g., “ROLE_USER”, “ROLE_ADMIN”)
- Required: Yes (
nullable = false) - Enum Type:
STRING(stores the enum name rather than ordinal)
Role Inclusion in JWT
When a user logs in, their role is embedded in the JWT token. This happens inUserServiceImpl.java:59:
JwtUtil.java:23):
Role Extraction from JWT
When validating requests, the role is extracted from the token (JwtUtil.java:43-46):
Permissions for Each Role
Here’s a comprehensive breakdown of what each role can do:ROLE_USER Permissions
ROLE_USER Permissions
Allowed Operations:
- Register a new account (
POST /auth/signup) - Login to the system (
POST /auth/login) - View own user information (
GET /users/me)
- View all users (
GET /admin/users) - Returns 403 Forbidden - Any administrative functions
ROLE_ADMIN Permissions
ROLE_ADMIN Permissions
Allowed Operations:
- All public endpoints (signup, login)
- View all users in the system (
GET /admin/users) - Administrative operations
/users/me if it strictly requires ROLE_USER and the admin doesn’t have that role.Endpoint Access Matrix
This table shows which roles can access each endpoint:| Endpoint | Method | ROLE_USER | ROLE_ADMIN | Authentication Required |
|---|---|---|---|---|
/auth/signup | POST | ✅ | ✅ | No |
/auth/login | POST | ✅ | ✅ | No |
/users/me | GET | ✅ | ❌* | Yes |
/admin/users | GET | ❌ | ✅ | Yes |
*Based on the current security configuration (
SecurityConfig.java:29), /users/me requires ROLE_USER authority specifically. This means admins with only ROLE_ADMIN cannot access it. In a typical implementation, you might want to use hasAnyAuthority("ROLE_USER", "ROLE_ADMIN") to allow both roles.Security Configuration Reference
The endpoint protection is defined inSecurityConfig.java:27-31:
How to Assign Roles
Default Assignment (Automatic)
All users who register through/auth/signup automatically receive ROLE_USER:
Admin Assignment (Manual)
Currently, there’s no public endpoint to create admin users. Admin roles must be assigned through:- Direct Database Modification: Update the user’s role column directly
- Database Seeding: Create admin users through initialization scripts
- Administrative Endpoint: Implement a protected endpoint for role management (not currently available)
Role-Based Response Filtering
While the current implementation doesn’t show this, you can filter response data based on roles. For example:Testing Role-Based Access
Create a Regular User
ROLE_USER
Login as User
Test User Access
Test Admin Access
Common Scenarios
Promoting a User to Admin
Promoting a User to Admin
Since there’s no built-in endpoint, you need to update the database directly:The user must login again to receive a new JWT token with the updated role.
Checking Current User's Role
Checking Current User's Role
The role is included in the JWT token and can be decoded client-side (though not verified without the secret).Alternatively, return the role in the login response or create a
/users/me/role endpoint.Handling Role Changes
Handling Role Changes
If a user’s role changes in the database:
- The change doesn’t affect existing JWT tokens (they still have the old role)
- The user must login again to get a new token with the updated role
- Consider implementing token invalidation if immediate role changes are needed
Best Practices
1. Never Trust Client-Provided Roles
Always fetch the role from the database during login, never accept it from the client:2. Use Enums for Type Safety
The enum-based role system prevents typos and invalid values:3. Centralize Authorization Logic
Keep authorization rules inSecurityConfig rather than scattering them across controllers:
4. Consider a Role Hierarchy
For more complex systems, consider implementing a role hierarchy where admins automatically inherit user permissions:Future Enhancements
Consider implementing:- Additional Roles: Add roles like
ROLE_MODERATOR,ROLE_PREMIUM_USER, etc. - Fine-Grained Permissions: Move beyond roles to individual permissions
- Role Management Endpoints: Allow admins to change user roles via API
- Role Auditing: Track when and by whom roles were changed
- Multi-Role Support: Allow users to have multiple roles simultaneously
Next Steps
Authentication
Learn how JWT authentication works
Authorization
Understand how roles enforce access control