Good day everyone. Interested in the question of how to record user data in the log - file when it enters the MVC application to which SpringSecurity is connected. For the registration page, I write the user data as follows: in the page controller, I create a logger and the saveUser method writes the user information to the log file as follows.
@Controller @RequestMapping("/registration") public class RegistrationController { private static final Logger logger = Logger.getLogger(RegistrationController.class.getName()); @Autowired PersonService personService; @Autowired CityService cityService; @Autowired MessageSource messageSource; @Autowired RoleService roleService; @RequestMapping(method = RequestMethod.GET) public String renderRegistration(ModelMap model) { Persons person = new Persons(); model.addAttribute("userForm", person); model.addAttribute("edit", false); model.addAttribute("loggedinuser", getPrincipal()); return "registration"; } @RequestMapping(value = "/newUser", method = RequestMethod.POST) public String saveUser(@Valid @ModelAttribute("userForm") Persons person, BindingResult result, ModelMap model) { List<FieldError> errors = new ArrayList<>(); if (result.hasErrors()) { return "errorPage"; } if (person.getNickname().isEmpty()) { FieldError nicknameError = new FieldError("person", "nickname", messageSource.getMessage("NotEmpty.person.nickname", new String[]{person.getNickname()}, Locale.getDefault())); errors.add(nicknameError); } if (!personService.isPersonsNicknameUnique(person.getPersonId(), person.getNickname())) { FieldError nicknameUniqError = new FieldError("person", "nickname", messageSource.getMessage("non.unique.nickname", new String[]{person.getNickname()}, Locale.getDefault())); errors.add(nicknameUniqError); } if (person.getPassword().isEmpty()) { FieldError passwordError = new FieldError("person", "password", messageSource.getMessage("NotEmpty.person.password", new String[]{person.getNickname()}, Locale.getDefault())); errors.add(passwordError); } if (person.getFirstName().isEmpty()) { FieldError firstNameError = new FieldError("person", "firstName", messageSource.getMessage("NotEmpty.person.firstName", new String[]{person.getNickname()}, Locale.getDefault())); errors.add(firstNameError); } if (person.getLastName().isEmpty()) { FieldError lastNameError = new FieldError("person", "lastName", messageSource.getMessage("NotEmpty.person.lastName", new String[]{person.getNickname()}, Locale.getDefault())); errors.add(lastNameError); } if (person.getEmail().isEmpty()) { FieldError emailError = new FieldError("person", "email", messageSource.getMessage("NotEmpty.person.email", new String[]{person.getNickname()}, Locale.getDefault())); errors.add(emailError); } if (person.getCity().equals(null)) { FieldError cityError = new FieldError("person", "city", messageSource.getMessage("NotEmpty.person.city", new String[]{person.getNickname()}, Locale.getDefault())); errors.add(cityError); } if (!errors.isEmpty()) { for (FieldError error : errors) { result.addError(error); } return "registration"; } // person.setRole(roleService.findByType("USER")); personService.savePerson(person); if (Const.DEBUG) { if (logger.isDebugEnabled()) { logger.debug("person: id-" + person.getPersonId() + " Nickname-" + person.getNickname() + " Password-" + person.getPassword() + " Lastname-" + person.getLastName() + " FirstName-" + person.getFirstName() + " Email-" + person.getEmail() + " City-" + person.getCity().getCityName() + " MobileNumber-" + person.getMobileNumber()); } } return "success"; } @ModelAttribute("rollers") public List<Rollers> getRollers() { return roleService.findAll();} @ModelAttribute("cities") public List<Cities> initializeCities() { return cityService.getAll(); } private String getPrincipal() { String userName = null; Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof UserDetails) { userName = ((UserDetails) principal).getUsername(); } else { userName = principal.toString(); } return userName; } } I need to do a similar operation when the user logs in, but since I have SpringSecurity connected, it processes the POST method, as a result I don’t understand how I write the user data to a file. PS: do not scold the code, I know it is not very)
Tried to do so:
@Component public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { public static final Logger logger = Logger.getLogger(CustomSuccessHandler.class.getName()); private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); @Override protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { String targetUrl = determineTargetUrl(authentication); if (response.isCommitted()) { System.out.println("Can't redirect"); return; } // String userName; // Object principal = authentication.getPrincipal(); // if (principal instanceof UserDetails) { // userName = ((UserDetails) principal).getUsername(); // } else { // userName = principal.toString(); // } // if (Const.DEBUG) { // if (logger.isDebugEnabled()) { logger.debug("person: Nickname-" + authentication.getPrincipal().toString()); logger.debug("person: Nickname-"); // } // } redirectStrategy.sendRedirect(request, response, targetUrl); } /* * This method extracts the roles of currently logged-in user and returns * appropriate URL according to his/her role. */ protected String determineTargetUrl(Authentication authentication) { String url = ""; Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); // для одной роли GrantedAuthority auth = authorities.iterator().next(); String role = auth.getAuthority(); // для нескольких ролей // List<String> roles = new ArrayList<String>(); // for (GrantedAuthority a : authorities) { // roles.add(a.getAuthority()); // } switch (role) { case "ROLE_USER": url = "/user"; break; case "ROLE_DRIVER": url = "/driver"; break; case "ROLE_OWNER": url = "/owner"; break; case "ROLE_ADMIN": url = "/admin"; break; default: url = "/accessDenied"; } return url; } public void setRedirectStrategy(RedirectStrategy redirectStrategy) { this.redirectStrategy = redirectStrategy; } protected RedirectStrategy getRedirectStrategy() { return redirectStrategy; } } in SecurityConfiguration:
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ // // @Autowired // LoginSuccess loginSuccess; @Autowired CustomSuccessHandler customSuccessHandler; @Autowired @Qualifier("customUserDetailsService") UserDetailsService userDetailsService; @Autowired public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/home").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasRole("USER") .antMatchers("/driver/**").hasRole("DRIVER") .antMatchers("/owner/**").hasRole("OWNER") .and().formLogin().loginPage("/login").successHandler(customSuccessHandler) // .successHandler(loginSuccess) .usernameParameter("ssoId").passwordParameter("password") .and().csrf() .and().exceptionHandling().accessDeniedPage("/Access_Denied"); // http.addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); } @Bean public AuthenticationTrustResolver getAuthenticationTrustResolver() { return new AuthenticationTrustResolverImpl(); } } also did not help. Also tried through onAuthenticationSuccess - also failed.
Log4j settings:
log4j.logger.com.team.mvc.configuration.CustomSuccessHandler=INFO, CustomSuccessHandler log4j.additivity.com.team.mvc.configuration.CustomSuccessHandler=false log4j.appender.CustomSuccessHandler=org.apache.log4j.RollingFileAppender log4j.appender.CustomSuccessHandler.File=E:\\LoginSuccess.out log4j.appender.CustomSuccessHandler.layout=org.apache.log4j.PatternLayout log4j.appender.CustomSuccessHandler.layout.ConversionPattern=[%p] %d{yyyy-MM-dd hh:mm:ss} %C:%M:%L - %m%n And when I tried through the filter, I could not get the security context, and the getPrincipal method threw a NullPointException. There are no exceptions at this time, but nothing is written to the log either.