Spring mvc SecurityContextHolder.getContext().getAuthentication().getPrincipal()在控制器上为空
我有一个SpringMVC应用程序,我在其中公开了一个端点,还有一个小库,我在其中编写了一些常用功能 我有这样一个实用程序类:Spring mvc SecurityContextHolder.getContext().getAuthentication().getPrincipal()在控制器上为空,spring-mvc,spring-security,Spring Mvc,Spring Security,我有一个SpringMVC应用程序,我在其中公开了一个端点,还有一个小库,我在其中编写了一些常用功能 我有这样一个实用程序类: class SecurityUtil { public static Principal getPrincipal(){ return SecurityContextHolder.getContext().getAuthentication() .getPrincipal(); } } class MyCo
class SecurityUtil {
public static Principal getPrincipal(){
return SecurityContextHolder.getContext().getAuthentication()
.getPrincipal();
}
}
class MyController {
public ResponseEntity<Void> myEndpoint(){
// do something
Principal principal = SecurityContextHolder.getContext()
.getAuthentication()
.getPrincipal();
// use the principal information for some audit processes
}
}
在控制器上,我做了如下工作:
class MyController {
public ResponseEntity<Void> myEndpoint(){
// do something
Principal principal = SecurityUtil.getPrincipal();
// use the principal information for some audit processes
}
}
在这种情况下,主体
不是空的,它包含我需要的信息。你知道会发生什么吗?我也遇到了同样的问题,然后我用以下方式解决了它 创建
UserService
界面
public interface UserService {
String getLoggedInUserName();
User getLoggedInUser();
}
为UserService
提供一个实现,但是,您也可以在不创建接口的情况下通过简单地将UserService创建为类来实现它
@Service
public class UserServiceImpl implements UserService {
private static Log log = LogFactory.getLog(UserServiceImpl.class);
@Override
public String getLoggedInUserName() {
try {
return getLoggedInUser().getUsername();
} catch (Exception ex) {
throw new UsernameNotFoundException("Please Log in", ex);
}
}
@Override
public User getLoggedInUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication.getPrincipal() instanceof User) {
return (User) authentication.getPrincipal();
} else {
throw new UsernameNotFoundException("User is not authenticated; Found " + authentication.getPrincipal() + " of type " + authentication.getPrincipal().getClass() + "; Expected type User");
}
}
}
通过自动连线调用userService.getLoggedInUserName()
@Autowired UserService userService
更新:
如果只在控制器中获取它们,那么只需将Principal作为方法参数传递给控制器方法,而不是从安全上下文获取。它将自动连接到控制器,稍后您可以将其传递给您的服务方法。这种方式也被认为是一种良好的做法
@RequestMapping(value=“/myEndpoint”,method=GET)
公共响应myEndpoint(主要负责人){
//做点什么
//将主要信息用于某些审核流程
}
我刚测试过,没关系。我仍然得到一个空值,你是否作为Springbean访问SecurityUtil
?嗯,这对我也不起作用。UserService和UserServiceImpl在jar中吗?或者直接在MVC项目中直接在我的项目中,但是我认为把它们放在罐子里也不会引起任何问题,我已经测试过了。如果你只在你的控制器中得到它们,那么你可以简单地将Principal
作为方法参数传递给你的控制器方法,而不是从安全上下文中得到它。谢谢Naresh Joshi,我的应用程序上下文中有一个错误,现在它开始工作了
@RequestMapping(value = "/myEndpoint", method = GET)
public ResponseEntity<Void> myEndpoint(Principal principal){
// do something
// use the principal information for some audit processes
}