如何使用SpringSecurity编辑UserProfile后获取ActiveUser

时间:2017-03-07 10:27:55

标签: java hibernate spring-mvc spring-security

我有一个页面,用户可以在其中编辑其个人资料。我可以使用以下控制器在 @AuthenticationPrincipal 的帮助下获得用户模型: -

@RequestMapping(value = "/editCustomerProfile", method = RequestMethod.GET)
public String editCustomerProfileGet(@AuthenticationPrincipal User  activeUser,Locale locale, Model model) {
Customer customer = customerService.getCustomerByUsername(activeUser.getUsername());
            model.addAttribute("customer", customer);
            return "editCustomer";
        }

更新控制器方法如下: -

@RequestMapping(value = "/updateCustomer", method = RequestMethod.POST)
    public String updateCustomerProfilePost(@Valid @ModelAttribute("customer") Customer customer, BindingResult result, Model model, HttpServletRequest request){

        customerFormValidator.validate(customer, result);
        if(result.hasErrors()){
            model.addAttribute("customer", customer);
            return "editCustomer";
        }

        List<Customer> customerList = customerService.getAllCustomers();

        for (int i=0; i< customerList.size(); i++){
            if(customer.getUsername().equals(customerList.get(i).getUsername())){
                model.addAttribute("usernameMsg", "Username already exists");
                model.addAttribute("customer", customer);
                return "editCustomer";
            }
        }

        Customer existingCustomer=customerService.getCustomerById(customer.getCutomerId());
        existingCustomer.setCustomerName(customer.getCustomerName());
        existingCustomer.setBillingAddress(customer.getBillingAddress());
        existingCustomer.getBillingAddress().setCustomer(existingCustomer);
        existingCustomer.setShippingAddress(customer.getShippingAddress());
        existingCustomer.getShippingAddress().setCustomer(existingCustomer);
        existingCustomer.setUsername(customer.getUsername());
        existingCustomer.getUser().setUsername(customer.getUsername());
        Customer editedCustomer=customerService.updateCustomer(existingCustomer);

        customerSecurityService.updateEditCustomerUserAuthentication(editedCustomer, request);

        model.addAttribute("message", "Customer Information Updated Successfully.");
        return "editCustomerSuccess";//information page
    }

使用CustomerSecurityServiceImpl的方法如下: -

@Override
    public void updateEditCustomerUserAuthentication(Customer customer, HttpServletRequest request) {
        final Users user = customer.getUser();
        final Authorities authorities = customerService.getUserAuthoritiesById(user.getUsersId());
        UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(user.getUsername(),null, Arrays.asList(new SimpleGrantedAuthority(authorities.getAuthority())));
        result.setDetails(user);
        SecurityContextHolder.getContext().setAuthentication(result);

    }

用户个人资料更改一次后出现错误,然后再次尝试引发错误,如下所示: -

  

SEVERE:Servlet [dispatcher]的Servlet.service()在路径[/ MusicStore]的上下文中引发了异常[请求处理失败;具有根本原因的嵌套异常是java.lang.NullPointerException]   显示java.lang.NullPointerException       at com.emusicstore.controller.RegisterController.editCustomerProfileGet(RegisterController.java:291)       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)       at java.lang.reflect.Method.invoke(Unknown Source)       在org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)       在org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)       在org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)       在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)       在org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)       在org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)       在org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)       在org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)       在org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)       在org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)       在javax.servlet.http.HttpServlet.service(HttpServlet.java:622)       在org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)       在javax.servlet.http.HttpServlet.service(HttpServlet.java:729)       在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)       在org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)       在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:330)       在org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)       在org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)       在org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)       在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:342)       在org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)       在org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)       在org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)       在org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)       在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)       在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)       在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)       在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)       在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)       在org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)       在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)       在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)       在org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)       at org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:674)       在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1500)       在org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run(NioEndpoint.java:1456)       at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)       at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)       at org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)       在java.lang.Thread.run(未知来源)

编辑用户信息后,它反映正确,但当我再次尝试编辑同一用户时, @AuthenticationPrincipal 活动用户返回null。请告诉我如何在身份验证原则中添加用户以重用上述 editCustomerProfileGet 方法。

非常感谢。

1 个答案:

答案 0 :(得分:0)

实际上你已经在身份验证令牌中传递了用户名作为主体,而需要传递用户对象,这将在内部的后续身份验证调用中使用。

将您的代码更改为

UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(user,user.getPassword(), Arrays.asList(new SimpleGrantedAuthority(authorities.getAuthority())));