【问题标题】:@SessionAtribute call issue in @RequestMapping@RequestMapping 中的@SessionAtribute 调用问题
【发布时间】:2018-09-28 01:01:53
【问题描述】:

我使用 Spring Security 进行身份验证。因为我想访问用户对象,所以我将这个身份验证保存在 @SessionAttribut 中。

建议方法

@ControllerAdvice(basePackages= {"com.sencerseven.blog.admin","com.sencerseven.blog.controller"})
@SessionAttributes("User")
public class SessionScope {

    @Autowired
    private UserService userService;

    @ModelAttribute("User")
    public User session() {
        Authentication authentication = 
        SecurityContextHolder.getContext().getAuthentication();

            if(authentication != null) {
                User user = userService.getByEmail(authentication.getName());
                if(user != null) {
                    return user;    
                }

            }
            return null;
    }
}

控制器

@Controller
@RequestMapping("/post")
public class PostController {


@RequestMapping(value= {"/{post}"})
public ModelAndView postPage(@SessionAttribute("User")User tempUser,@PathVariable("post")String tempPostName ) throws NotFoundException  {
 ...
 .....
}


@PostMapping("addcomment")
@ResponseBody
public String saveComment(@SessionAttribute("User")User tempUser,@RequestParam("post_id")int id,@RequestParam("comment")String tempComment) {
 ....
 .....
}


}

@SessionAttribute("User") 在 PostPage 方法中返回 null,页面抛出异常

 java.lang.NullPointerException at com.sencerseven.blog.controller.PostController.postPage(PostController.jav   a:54) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at 

.但是SaveComment方法是正确的。SaveComment访问用户对象中的@SessionAttribute("User")它不是null返回。

为什么?我该如何解决这个问题?

【问题讨论】:

  • 由于 session() 在身份验证失败时返回 null,也许它就在这里。尝试返回默认用户或打印日志来验证这一点。
  • 使用不在它周围的框架。 Spring Security 允许您简单地注入 Authentication 对象或您自己的用户,您不需要自己将其添加到会话中。请参阅 docs.spring.io/spring-security/site/docs/current/reference/html/… 并使用它而不是解决它。
  • 另外,正如我在您的另一个(现已删除?)问题中提到的那样,@SessionAttributes@SessionAttribute 是不同的东西,不应该这样使用。跨度>

标签: java spring session spring-security


【解决方案1】:

Spring Security 已经支持这种开箱即用的功能(如文档中的 here 所述)。你试图在你自己的实现中硬塞,让事情变得复杂。不要使用@SessionAttribute,而是使用@AuthenticationPrincipal 注解让Spring Security 找到并注入用户。

所以基本上删除您的SessionScope 控制器建议并在您的控制器上用@AuthenticationPrincipal 替换@SessionAttribute

@Controller
@RequestMapping("/post")
public class PostController {


    @RequestMapping(value= {"/{post}"})
    public ModelAndView postPage(@AuthenticationPrincipal User tempUser, @PathVariable("post") String tempPostName ) throws NotFoundException  {
        ...
    }

    @PostMapping("addcomment")
    @ResponseBody
    public String saveComment(@AuthenticationPrincipal User tempUser, @RequestParam("post_id") int id, @RequestParam("comment") String tempComment) {
        ...
    }       
}

您必须确保您自己的 User 也是 Spring Security 使用的 User。如果不是这种情况,请使用自定义 AuthenticationSuccessHandler 而不是控制器建议,它将您自己的 User 添加到 Session 一次(而不是在每个请求上)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多