Itsurran
Itsurran
JCHJava Community | Help. Code. Learn.
Created by Itsurran on 2/6/2025 in #java-help
Roles & SecurityConfig
Hello so i have 3 roles
public enum Role {
ADMIN,
STAFF,
USER;
}
public enum Role {
ADMIN,
STAFF,
USER;
}
and i'm trying to write the authorities etc and here is my config
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(request -> request
.requestMatchers("/api/v1/auth/**", "/ws/**").permitAll()

.requestMatchers("/api/v1/admin/**").hasAuthority("ADMIN")

.requestMatchers("/api/v1/staff/**").hasAuthority("STAFF")

.requestMatchers("/api/v1/user/**").hasAuthority("USER")

.requestMatchers("/api/v1/adminuser/**").hasAnyAuthority("ADMIN", "USER")

.requestMatchers("/api/v1/logs/**").hasAnyAuthority("STAFF", "ADMIN")

.anyRequest().authenticated()
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
)
.authenticationProvider(authenticationProvider)
.addFilterBefore(new SessionAuthenticationFilter(userSessionService), UsernamePasswordAuthenticationFilter.class)
.logout(logout -> logout
.logoutUrl("/api/v1/auth/logout")
.addLogoutHandler(logoutService)
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext())
);

return http.build();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeHttpRequests(request -> request
.requestMatchers("/api/v1/auth/**", "/ws/**").permitAll()

.requestMatchers("/api/v1/admin/**").hasAuthority("ADMIN")

.requestMatchers("/api/v1/staff/**").hasAuthority("STAFF")

.requestMatchers("/api/v1/user/**").hasAuthority("USER")

.requestMatchers("/api/v1/adminuser/**").hasAnyAuthority("ADMIN", "USER")

.requestMatchers("/api/v1/logs/**").hasAnyAuthority("STAFF", "ADMIN")

.anyRequest().authenticated()
)
.sessionManagement(session -> session
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
)
.authenticationProvider(authenticationProvider)
.addFilterBefore(new SessionAuthenticationFilter(userSessionService), UsernamePasswordAuthenticationFilter.class)
.logout(logout -> logout
.logoutUrl("/api/v1/auth/logout")
.addLogoutHandler(logoutService)
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext())
);

return http.build();
}
but for some reason when i hit this endpoint that requries it to be ADMIN such as this endpoint
@RestController
@RequestMapping("/api/v1/admin")
@RequiredArgsConstructor
public class AdminController {

private final InvitationService invitationService;

@PostMapping("/invite")
@PreAuthorize("hasAuthority('ADMIN')")
public ResponseEntity<String> createInvitation(@RequestParam String email) throws MessagingException {
String response = invitationService.createInvitation(email);
return ResponseEntity.ok(response);
}
@RestController
@RequestMapping("/api/v1/admin")
@RequiredArgsConstructor
public class AdminController {

private final InvitationService invitationService;

@PostMapping("/invite")
@PreAuthorize("hasAuthority('ADMIN')")
public ResponseEntity<String> createInvitation(@RequestParam String email) throws MessagingException {
String response = invitationService.createInvitation(email);
return ResponseEntity.ok(response);
}
it doesnt let me even when i'm authenticated and have a session. But when i change the securityconfig
.requestMatchers("/api/v1/admin/**").hasAuthority("ADMIN")
.requestMatchers("/api/v1/admin/**").hasAuthority("ADMIN")
to
.requestMatchers("/api/v1/admin/**").permitAll()
.requestMatchers("/api/v1/admin/**").permitAll()
then it works
48 replies
JCHJava Community | Help. Code. Learn.
Created by Itsurran on 2/4/2025 in #java-help
Websocket Postman
I just wanted to check if someone notice anything wrong in my code. Basically, what I want to do is that when a new user registers, I want the admins to be notified with "New user has been registered", but I want to do it in real-time using WebSocket. I'm testing my WebSocket URL ws://localhost:8080/ws, and I successfully connect to it. I also subscribe to the destination:
destination:/topic/admins
id:sub-0
destination:/topic/admins
id:sub-0
which works fine. But when I register a new user, I don't receive the message in the destination, even though I see it in the terminal 😅 hahaha. It's weird, but I just wanted to check if someone notice anything off. WebsocketConfig
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("*");
}

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("*");
}

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
NotificationService
@Service
public class NotificationService {

private static final Logger logger = LoggerFactory.getLogger(NotificationService.class);
private final SimpMessagingTemplate messagingTemplate;

public NotificationService(SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}

public void notifyAdmin(String message) {
logger.info("Sending WebSocket message to /topic/admins: {}", message);
messagingTemplate.convertAndSend("/topic/admins", message);
logger.info(" WebSocket message sent successfully!");
}
}
@Service
public class NotificationService {

private static final Logger logger = LoggerFactory.getLogger(NotificationService.class);
private final SimpMessagingTemplate messagingTemplate;

public NotificationService(SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}

public void notifyAdmin(String message) {
logger.info("Sending WebSocket message to /topic/admins: {}", message);
messagingTemplate.convertAndSend("/topic/admins", message);
logger.info(" WebSocket message sent successfully!");
}
}
AuthService
User user = createUser(request);
userRepository.save(user);

System.out.println("User registered: " + user.getFirstname() + " " + user.getLastname());

notificationService.notifyAdmin("New user registered: " + user.getFirstname() + " " + user.getLastname());
System.out.println(" WebSocket message sent for user registration!");

return ResponseEntity.status(HttpStatus.CREATED)
.body(new AuthenticationResponse("User successfully registered"));
User user = createUser(request);
userRepository.save(user);

System.out.println("User registered: " + user.getFirstname() + " " + user.getLastname());

notificationService.notifyAdmin("New user registered: " + user.getFirstname() + " " + user.getLastname());
System.out.println(" WebSocket message sent for user registration!");

return ResponseEntity.status(HttpStatus.CREATED)
.body(new AuthenticationResponse("User successfully registered"));
211 replies
JCHJava Community | Help. Code. Learn.
Created by Itsurran on 6/21/2024 in #java-help
Resetting password access denied
Hello im trying to fix that a user can reset their password by hitting this endpoint /api/reset-password/password currently im getting access denied but i dont want the users to be authed to use this endpoint. Im gonna share few code if you guys can help me find the issue and i would really appericate it since ive been on this all day. PasswordResetController
@RestController
@RequestMapping("/api/reset-password")
public class PasswordResetController {

@Autowired
private PasswordResetService passwordResetService;

@Autowired
private UserService userService;

@PostMapping("/password")
public ResponseEntity<?> requestResetPassword(@RequestParam String email) {
User user = userService.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + email));

// Create and send password reset token via email
passwordResetService.createPasswordResetToken(user);

return ResponseEntity.ok().build();
}
}
@RestController
@RequestMapping("/api/reset-password")
public class PasswordResetController {

@Autowired
private PasswordResetService passwordResetService;

@Autowired
private UserService userService;

@PostMapping("/password")
public ResponseEntity<?> requestResetPassword(@RequestParam String email) {
User user = userService.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + email));

// Create and send password reset token via email
passwordResetService.createPasswordResetToken(user);

return ResponseEntity.ok().build();
}
}
PasswordResetService
public class PasswordResetService {

@Autowired
private TokenRepository tokenRepository;

@Transactional
public Token createPasswordResetToken(User user) {
invalidateExistingTokens(user);

String tokenValue = UUID.randomUUID().toString();
Token passwordResetToken = Token.builder()
.token(tokenValue)
.tokenType(TokenType.PASSWORD_RESET)
.user(user)
.expiryDate(calculateExpiryDate())
.expired(false)
.revoked(false)
.build();

return tokenRepository.save(passwordResetToken);
}

private void invalidateExistingTokens(User user) {
tokenRepository.findByUserAndTokenType(user, TokenType.PASSWORD_RESET)
.ifPresent(token -> {
token.setExpired(true);
tokenRepository.save(token);
});
}

private Date calculateExpiryDate() {
long ONE_HOUR_IN_MILLIS = 1000 * 60 * 60;
return new Date(System.currentTimeMillis() + ONE_HOUR_IN_MILLIS);
}
public class PasswordResetService {

@Autowired
private TokenRepository tokenRepository;

@Transactional
public Token createPasswordResetToken(User user) {
invalidateExistingTokens(user);

String tokenValue = UUID.randomUUID().toString();
Token passwordResetToken = Token.builder()
.token(tokenValue)
.tokenType(TokenType.PASSWORD_RESET)
.user(user)
.expiryDate(calculateExpiryDate())
.expired(false)
.revoked(false)
.build();

return tokenRepository.save(passwordResetToken);
}

private void invalidateExistingTokens(User user) {
tokenRepository.findByUserAndTokenType(user, TokenType.PASSWORD_RESET)
.ifPresent(token -> {
token.setExpired(true);
tokenRepository.save(token);
});
}

private Date calculateExpiryDate() {
long ONE_HOUR_IN_MILLIS = 1000 * 60 * 60;
return new Date(System.currentTimeMillis() + ONE_HOUR_IN_MILLIS);
}
SecurityConfiguration
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeHttpRequests()
.requestMatchers("/api/v1/auth/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
.logout()
.logoutUrl("/api/v1/auth/logout")
.addLogoutHandler(logoutHandler)
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext()
);
return http.build();
}
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeHttpRequests()
.requestMatchers("/api/v1/auth/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
.logout()
.logoutUrl("/api/v1/auth/logout")
.addLogoutHandler(logoutHandler)
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext()
);
return http.build();
}
10 replies
JCHJava Community | Help. Code. Learn.
Created by Itsurran on 5/19/2024 in #java-help
Websocket 1-1 chat between authenticated users
Hello i'm wondering how to send message to a specific logged in user using spring web sockets I have assigned a UUID to each user when he signups, and after login each user gets a JWT token for session authentication But i'm trying for a long time fixing a 1-1 chat between users that exists in the db. For example if i have 2 users logged in, i can then click on the user then it should subscribe to a chat room between them and i can then chat in real time. I have been confused for a long time since there isnt alot of documents of this. If someone can either guide me through this process real quick or maybe explain it fast it would be awesome! thanks.
17 replies
JCHJava Community | Help. Code. Learn.
Created by Itsurran on 3/25/2024 in #java-help
Delete user
Hi guys im trying to delete a user from the database but i keep getting 403 cant seem to find the problem
@DeleteMapping("/user/{id}")
public ResponseEntity<String> deleteUserById(@PathVariable UUID id) {
userService.deleteUserById(id);
return ResponseEntity.ok("User deleted successfully");
}
@DeleteMapping("/user/{id}")
public ResponseEntity<String> deleteUserById(@PathVariable UUID id) {
userService.deleteUserById(id);
return ResponseEntity.ok("User deleted successfully");
}
public void deleteUserById(UUID id) {
userRepository.deleteById(id);
}
public void deleteUserById(UUID id) {
userRepository.deleteById(id);
}
im getting 403 error in postman deleting a user with the id this is picture of me debugging it Note: I have the user already in my database with the id https://cdn.discordapp.com/attachments/653632542100160547/1221828244882591804/image.png?ex=6613ff3a&is=66018a3a&hm=31741475b0eb312cc675b6459d8bac920bd2fd3628527e3a2d0803432abb650e&
86 replies
JCHJava Community | Help. Code. Learn.
Created by Itsurran on 3/23/2024 in #java-help
Websocket + spring boot 3 with reactjs
Hello, I have never worked with Websocket before and I’m trying to learn it, i have read a lot articles and I can’t seem to find what I’m looking for so I would be pleased and grateful if you can take your time.
4 replies
JCHJava Community | Help. Code. Learn.
Created by Itsurran on 2/8/2024 in #java-help
UserprofileImage
Hi, i have never worked around a userprofileimage before so i followed this link to store the files in s3 bucket. But i'm wondering how i can create a userprofileimage, is there any articles or tutorials i can follow around? Note: I already have a user table. https://medium.com/@mertcakmak2/object-storage-with-spring-boot-and-aws-s3-64448c91018f
4 replies
JCHJava Community | Help. Code. Learn.
Created by Itsurran on 2/5/2024 in #java-help
Access Denied
Hello, i have been trying to fix this alone for around a day now and i'm giving up. I'm trying to get a user id with uuid in the postman but im getting access denied and i have also debugged it. UserService
public User findUserById(UUID id) {
return userRepository.findUserById(id);
}
}
public User findUserById(UUID id) {
return userRepository.findUserById(id);
}
}
UserRepository
public interface UserRepository extends JpaRepository<User, UUID> {

Optional<User> findByEmail(String email);

boolean existsByFirstname (String firstname);
boolean existsByEmail(String email);

List<User> findAllBy();
User findUserById(UUID id);


}
public interface UserRepository extends JpaRepository<User, UUID> {

Optional<User> findByEmail(String email);

boolean existsByFirstname (String firstname);
boolean existsByEmail(String email);

List<User> findAllBy();
User findUserById(UUID id);


}
AuthenticationController
@GetMapping("user/{id}")
public User findUserByid(@PathVariable UUID id) {
return userService.findUserById(id);
}
}
@GetMapping("user/{id}")
public User findUserByid(@PathVariable UUID id) {
return userService.findUserById(id);
}
}
the debug says
Securing GET /api/v1/auth/user/cd6dc7ec-2396-4852-9e35-72a0c5196dec
Securing GET /api/v1/auth/user/cd6dc7ec-2396-4852-9e35-72a0c5196dec
Set SecurityContextHolder to anonymous SecurityContext
Set SecurityContextHolder to anonymous SecurityContext
913 replies