2017-04-16 206 views
0

我正在体验我认为可能是一个错误。委托人返回为UsernamePasswordAuthenticationToken

我正在使用Spring Boot和Spring Security。通常情况下,一切都运行良好,但当我通过HttpServletRequest或直接从控制器获得委托人时,出于某种奇怪的原因将其转换为UsernamePasswordAuthenticationToken。当我使用SecurityContextHolder.getContext().getAuthentication().getPrincipal()时,它返回正确的对象。

请参阅下面的代码,请参阅最后6行左右的注释以了解实际返回的内容。

@RequestMapping(method = RequestMethod.POST) 
public ElementDto postElement(@RequestBody @Valid ElementDto element, BindingResult bindingResult, HttpServletRequest httpServletRequest, Principal principal) { 
    logger.info("postElement - {}", element); 
    if (bindingResult.hasErrors()) { 
     throw new SpringBootCommonError(bindingResult.getAllErrors().get(0).getDefaultMessage(), SpringBootCommonErrorEnum.VALIDATION); 
    } 
    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = (UsernamePasswordAuthenticationToken)principal; /*is of type UsernamePasswordAuthenticationToken*/ 
    Principal requestPrincipal = httpServletRequest.getUserPrincipal();/*is of type UsernamePasswordAuthenticationToken*/ 
    Principal principalFromCast = (Principal)usernamePasswordAuthenticationToken.getPrincipal();/*is of type User (what I want)*/ 
    Object securityPrincipal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();/*is of type (what I want)*/ 
    element.setUploadedBy(((User) httpServletRequest.getUserPrincipal()).getEntityNo()); 
    return elementService.createElement(element); 
} 

回答

2

UsernamePasswordAuthenticationToken是接口Authentication它扩展了界面Principal的实现。在JSE java.security中定义了PrincipalUsernamePasswordAuthenticationToken是Spring Security中的一个概念,它实现了Principal接口。

UsernamePasswordAuthenticationToken基本上是一个委托人。

/** 
    * The identity of the principal being authenticated. In the case of an authentication 
    * request with username and password, this would be the username. Callers are 
    * expected to populate the principal for an authentication request. 
    * <p> 
    * The <tt>AuthenticationManager</tt> implementation will often return an 
    * <tt>Authentication</tt> containing richer information as the principal for use by 
    * the application. Many of the authentication providers will create a 
    * {@code UserDetails} object as the principal. 
    * 
    * @return the <code>Principal</code> being authenticated or the authenticated 
    * principal after authentication. 
    */ 
    Object getPrincipal(); 

这是SecurityContextHolder.getContext().getAuthentication().getPrincipal();

getPrincipal()方法的Javadoc所以我会假设你真正想要的是一个UserDetails没有一个主体。

+0

我明白UsernamePasswordAuthenticationToken我的问题是,为什么是我的校长被返回UsernamePasswordAuthenticationToken例如下面的代码工作 '((用户)((UsernamePasswordAuthenticationToken)本金).getPrincipal())。getEntityNo()'但是这个代码不不是'((用户)主体).getEntityNo()' 我不认为我应该把它转换成UsernamePasswordAuthenticationToken,然后返回到本金,如果它最初是主体 –

+1

它不是很清楚,你指的是什么'委托人'在你的评论。这取决于身份验证提供程序如何实现它。 HttpServeletRequest和SecurityContext都会返回你正确的主体,即UsernamePasswordAuthenticationToken – Simon

-1

如果您还没有明确的配置,你想怎样,然后验证您的用户使用,Spring Security默认使用

DaoAuthenticationProvider 

针对使用

UsernamePasswordAuthenticationToken 

用于验证用户,如果认证正在使用用户名和密码来验证您的用户。

这就是为什么,当你试图让

Principal object 

你需要明确强制转换为

UsernamePasswordAuthenticationToken  

注意的原因:Spring Security提供许多其他的认证机制以及,说X .509,LDAP,甚至您也可以使用JDBC身份验证。