2017-04-16 5 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インタフェースPrincipalを拡張インタフェースAuthenticationの実装です。 Principalは、JSE java.securityに定義されています。 UsernamePasswordAuthenticationTokenは、Principalインターフェースを実装するSpring Securityのコンセプトです。

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(); 

これは、だから私は、あなたが実際にしたいことはUserDetailsない校長であると仮定しますSecurityContextHolder.getContext().getAuthentication().getPrincipal();

getPrincipal()メソッドのjavadocです。

+0

私は私の問題は私の主は、例えばUsernamePasswordAuthenticationTokenとして返されるされる理由を次のコードは、 '((ユーザ)((UsernamePasswordAuthenticationToken)校長).getPrincipal())。getEntityNo()'動作しますが、このコードはありませんUsernamePasswordAuthenticationTokenを理解します'((User)プリンシパル).getEntityNo() ' 私はそれをUsernamePasswordAuthenticationTokenにキャストして元のプリンシパルだった場合は元に戻す必要があるとは思わない –

+1

それはあまり明確ではないあなたのコメントに。それは、認証プロバイダーがそれをどのように実装するかによって異なります。 HttpServeletRequestとSecurityContextの両方がUsernamePasswordAuthenticationTokenである正しいプリンシパルを返します。 – Simon

-1

あなたは、あなたのユーザーを認証する方法を、明示的に設定していない場合場合は、デフォルトでは春のセキュリティは、ユーザーを認証するための

UsernamePasswordAuthenticationToken 

を使用して認証用

DaoAuthenticationProvider 

を使用していますUserNameとPasswordを使用してユーザーを認証しています。春のセキュリティは、他の多くの認証メカニズムを提供し、Xを言う:あなたは、あなたが

UsernamePasswordAuthenticationToken  

NOTEに明示的に型キャストする必要が

Principal object 

を取得しようとしている理由は、理由です

.509、LDAP、JDBC認証を使用することもできます。

関連する問題