我有一个Spring MVC应用程序,我正在暴露一个端点,还有一个小型库,我在其中编写了一些常用功能。
我有一个像这样的实用程序类:
class SecurityUtil {
public static Principal getPrincipal(){
return SecurityContextHolder.getContext().getAuthentication()
.getPrincipal();
}
}
从控制器我做的事情是:
class MyController {
public ResponseEntity<Void> myEndpoint(){
// do something
Principal principal = SecurityUtil.getPrincipal();
// use the principal information for some audit processes
}
}
在这种情况下,Principal
为空,但如果替换我的代码如下:
class MyController {
public ResponseEntity<Void> myEndpoint(){
// do something
Principal principal = SecurityContextHolder.getContext()
.getAuthentication()
.getPrincipal();
// use the principal information for some audit processes
}
}
在这种情况下,Principal
不为空,它具有我需要的信息
你知道会发生什么吗?
答案 0 :(得分:2)
我遇到了同样的问题,然后我按照以下方式解决了这个问题。
创建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()
UserService
@Autowired UserService userService
更新: 如果只是在控制器中获取它们,那么您只需将Principal principal作为方法参数传递给控制器方法,而不是从安全上下文中获取它。它将自动连接到控制器,稍后您可以将其传递给您的服务方法。这种方式也被认为是一种很好的做法Spring MVC, getting principal from security context in service layer
@RequestMapping(value = "/myEndpoint", method = GET)
public ResponseEntity<Void> myEndpoint(Principal principal){
// do something
// use the principal information for some audit processes
}