大家下午好。对他进入SpringSecurity所连接的MVC应用程序时如何将用户数据写入日志文件的问题感兴趣。对于注册页面,我将用户数据写入如下:在页面控制器中,我创建了一个记录器,并在 saveUser 方法中将用户信息写入日志文件,如下所示。
@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;
}
}
我需要在用户登录时做类似的操作,但是由于我连接了SpringSecurity,它处理了POST方法,最后我不明白如何将用户数据写入文件。PS:代码不要骂我,我知道不是很好)
试图这样做:
@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;
}
}
在安全配置中:
@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();
}
}
也没有帮助。也通过 onAuthenticationSuccess 尝试过 - 也没有用。
log4j 设置:
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
而当我尝试通过过滤器时,我无法获取安全上下文,getPrincipal 方法抛出了 NullPointException。这次没有异常,但也没有任何内容写入日志。
创建AuthenticationSuccessHandler
并在SpringSecurity配置中连接它。如果您需要了解失败的登录尝试,请创建一个AuthenticationFailureHandler。