【问题标题】:Validate user per every request and response in spring在春季根据每个请求和响应验证用户
【发布时间】:2017-08-28 05:31:55
【问题描述】:

由于我是 Spring 新手,并且我遇到了用户服务问题。我有管理面板和客户博客。当客户登录浏览器时,管理员已在客户表中将状态从 InActive 更改为 Active。但是用户会话处于活动状态。以便他可以在状态改变后进行处理。

我需要一种应该通用的通用方法。此方法应该是访问表并根据每个请求验证用户。我有一个控制器,它应该调用通用方法。因为我无法为每个班级编辑代码。在 JSP 和 Servlet 中,我使用 doFilter 处理了这个问题。如何在 Spring 中实现这一点..

AppInitializer.java

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[] { AppConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return null;
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/" };
}

@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
    registration.setMultipartConfig(getMultipartConfigElement());
}

private MultipartConfigElement getMultipartConfigElement() {
    MultipartConfigElement multipartConfigElement = new MultipartConfigElement( LOCATION, MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
    return multipartConfigElement;
}

private static final String LOCATION = "C:/temp/"; // Temporary location where files will be stored

private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
                                                    // Beyond that size spring will throw exception.
private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.

private static final int FILE_SIZE_THRESHOLD = 0;

}

AppConfig.java

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[] { AppConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return null;
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/" };
}

@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
    registration.setMultipartConfig(getMultipartConfigElement());
}

private MultipartConfigElement getMultipartConfigElement() {
    MultipartConfigElement multipartConfigElement = new MultipartConfigElement( LOCATION, MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
    return multipartConfigElement;
}

private static final String LOCATION = "C:/temp/"; // Temporary location where files will be stored

private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
                                                    // Beyond that size spring will throw exception.
private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.

private static final int FILE_SIZE_THRESHOLD = 0;

}

HibernateConfiguration.java

import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@ComponentScan({ "com.ppts.configuration" })
@PropertySource(value = { "classpath:application.properties" })
public class HibernateConfiguration {

@Autowired
private Environment environment;

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(new String[] { "com.ppts.model" });
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
 }

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
    dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
    dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
    dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
    return dataSource;
}

private Properties hibernateProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
    return properties;        
}

@Bean
@Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
   HibernateTransactionManager txManager = new HibernateTransactionManager();
   txManager.setSessionFactory(s);
   return txManager;
}
}

AppController.java

package com.sample.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;

import com.sample.handler.FileHandler;
import com.sample.model.Address;
import com.sample.model.Employee;
import com.sample.model.EmployeeDocument;
import com.sample.model.EmployeeSalary;
import com.sample.model.FileBucket;
import com.sample.model.User;
import com.sample.model.UserProfile;
import com.sample.service.EmployeeDocumentService;
import com.sample.service.EmployeeSalaryService;
import com.sample.service.EmployeeService;
import com.sample.service.UserProfileService;
import com.sample.service.UserService;
import com.sample.validators.FileValidator;

@Controller
@RequestMapping("/")
@SessionAttributes("roles")
public class AppController {

@Autowired
UserService userService;

@Autowired
EmployeeService employeeService;

@Autowired
EmployeeSalaryService employeeSalaryService;

@Autowired
UserProfileService userProfileService;

@Autowired
EmployeeDocumentService employeeDocumentService;

@Autowired
FileValidator fileValidator;

@InitBinder("fileBucket")
protected void initBinderFileBucket(WebDataBinder binder) {
    binder.setValidator(fileValidator);
}

@Autowired
MessageSource messageSource;

@Autowired
PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;

@Autowired
AuthenticationTrustResolver authenticationTrustResolver;

@RequestMapping(value = { "/", "/list" }, method = RequestMethod.GET)
public String adminPage(ModelMap model) {
    model.addAttribute("home",true);
    model.addAttribute("loggedinuser", getPrincipal());
    return "home";
}

@RequestMapping(value = { "/userList" }, method = RequestMethod.GET)
public String listUsers(ModelMap model) {
    List<User> users = userService.findAllUsers();
    model.addAttribute("users", users);
    model.addAttribute("loggedinuser", getPrincipal());
    return "userslist";
}

@RequestMapping(value = { "/newuser" }, method = RequestMethod.GET)
public String newUser(ModelMap model) {
    User user = new User();
    model.addAttribute("user", user);
    model.addAttribute("edit", false);
    model.addAttribute("loggedinuser", getPrincipal());
    return "registration";
}

@RequestMapping(value = { "/newuser" }, method = RequestMethod.POST)
public String saveUser(@Valid User user, BindingResult result,
        ModelMap model) {
    if (result.hasErrors()) {
        return "registration";
    }
    if(!userService.isUserSSOUnique(user.getId(), user.getSsoId())){
        FieldError ssoError =new FieldError("user","ssoId",messageSource.getMessage("non.unique.ssoId", new String[]{user.getSsoId()}, Locale.getDefault()));
        result.addError(ssoError);
        return "registration";
    }
    userService.saveUser(user);
    model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " registered successfully");
    model.addAttribute("loggedinuser", getPrincipal());
    return "registrationsuccess";
}

@RequestMapping(value = { "/edit-user-{ssoId}" }, method = RequestMethod.GET)
public String editUser(@PathVariable String ssoId, ModelMap model) {
    User user = userService.findBySSO(ssoId);
    model.addAttribute("user", user);
    model.addAttribute("edit", true);
    model.addAttribute("loggedinuser", getPrincipal());
    return "registration";
}

@RequestMapping(value = { "/edit-user-{ssoId}" }, method = RequestMethod.POST)
public String updateUser(@Valid User user, BindingResult result,
        ModelMap model, @PathVariable String ssoId) {
    if (result.hasErrors()) {
        return "registration";
    }
    userService.updateUser(user);
    model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " updated successfully");
    model.addAttribute("loggedinuser", getPrincipal());
    return "registrationsuccess";
}

//Update User and Employee By Id
@RequestMapping(value = { "/getUserById" }, method = RequestMethod.GET)
public String getUserSSOId(ModelMap model) {
    User user = new User();
    model.addAttribute("user", user);
    model.addAttribute("edit", true);
    model.addAttribute("loggedinuser", getPrincipal());
    return "userview";
}

@RequestMapping(value = { "/updateByUserId" }, method = RequestMethod.GET)
public String getByUserId( @ModelAttribute User userDetails,ModelMap model,BindingResult result) {
    User user =userService.findBySSO(userDetails.getSsoId());
    if(user!=null){
        model.addAttribute("user", user);
        model.addAttribute("edit", true);
        model.addAttribute("loggedinuser", getPrincipal());
        return "registration";
    }else{
        FieldError referenceIdError =new FieldError("user","ssoId",messageSource.getMessage("non.empty.userid.notexist", new String[]{userDetails.getSsoId()}, Locale.getDefault()));
        result.addError(referenceIdError);
        model.addAttribute("loggedinuser", getPrincipal());
        return "userview";
    }
}

@RequestMapping(value = { "/updateByUserId" }, method = RequestMethod.POST)
public String updateUserById(@Valid User user, BindingResult result,
        ModelMap model) {
    if (result.hasErrors()) {
        return "registration";
    }
    userService.updateUser(user);
    model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " updated successfully");
    model.addAttribute("loggedinuser", getPrincipal());
    return "registrationsuccess";
}

@RequestMapping(value = { "/deleteByUserId" }, method = RequestMethod.GET)
public String deleteUserById(ModelMap model) {
    User user = new User();
    model.addAttribute("user", user);
    model.addAttribute("delete", true);
    model.addAttribute("loggedinuser", getPrincipal());
    return "userview";
}

@RequestMapping(value = { "/deleteUserById" }, method = RequestMethod.GET)
public String deleteByuserId( @ModelAttribute User userDetails,ModelMap model,BindingResult result) {
    User user=userService.findBySSO(userDetails.getSsoId());
    if(user!=null){
        userService.deleteUserBySSO(userDetails.getSsoId());
        model.addAttribute("loggedinuser", getPrincipal());
        model.addAttribute("employeeSuccess", "Employee " + user.getFirstName() + " deleted successfully");
        return "registrationsuccess";
    }else{
        FieldError referenceIdError =new FieldError("employee","employeeReferenceId",messageSource.getMessage("non.empty.userid.notexist", new String[]{userDetails.getSsoId()}, Locale.getDefault()));
        model.addAttribute("loggedinuser", getPrincipal());
        result.addError(referenceIdError);
        return "userview";
    }

}
}

【问题讨论】:

  • 包含您的代码。
  • 布拉尼斯拉夫·拉齐奇。添加了我的代码和配置。

标签: java spring authentication controller


【解决方案1】:

您可以创建一个实现 Spring 的 HandlerInterceptor 接口的类。在Controller方法处理请求之前,每个请求都会调用它的preHandle方法。

由于您只想在处理每个请求之前对其进行验证检查,因此您可以创建一个扩展 HandlerInterceptorAdapter 类的类,该类为 HandlerInterceptor 接口中的所有方法提供方便的默认值。

您只需要根据您的业务规则为以下方法提供实现

preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

下面的示例代码

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class TransactionInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        // Your business logic goes here

        // return true or false depending on whether you want the controller to handle the request or terminate request processing.
    }
} 

您需要在 Spring Config 中注册拦截器,如下所示

@EnableWebMvc
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {

    .....
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new YourNewInterceptor());
    }
    .....

}   

【讨论】:

  • 在控制器中我应该如何调用这个类
  • 你不需要在Controller中显式调用这个类,preHandle方法会被Spring调用,然后再将控制权交给Controller并执行。
  • 这里我有一个疑问。我已经编写了访问表的代码以获取用户是否处于活动状态。但是如果用户不活跃,我需要重定向主页。否则它应该允许正常的过程。我可以用 UserLogInService 实现吗
  • @MuthuVikki 你可以在这里找到一个相关的查询,它应该回答你的问题stackoverflow.com/questions/22990378/…
  • 如何从拦截器调用服务。我得到空指针异常。有什么方法可以添加一些注释
【解决方案2】:

您也可以在 Filter 中执行此操作。你只需要用@Component 注释它,瞧。它变成了一个 Spring bean。像这样:

@Component
public class UserFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        User user = (User)request.getAttribute("user");
        // Do whatever you want with your user
    }

    @Override
    public void destroy() {

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多