2016-07-29 7 views
2

TokenEnhancerを実装して、承認サーバー側で生成されたトークンに関する追加情報を正常に追加しました。ここで生成されたトークンは次のとおりです。トークンadditionalInformationを使用して式ベースのアクセス制御を検証する方法

{"access_token":"ccae1713-00d4-49c2-adbf-e699c525d53e","token_type":"bearer","expires_in":31512,"scope":"end-user","user_id":2}

さて、RemoteTokenServicesを介して通信し、完全に独立した春のプロジェクトでリソースサーバ側、に、私はこの方法expression-based access controlで学位論文の情報を使用したいと思います。

@PreAuthorize("#oauth2.hasScope('admin') or #id == authentication.principal.user_id") @Override UserAccount findOne (@P("id") Integer id);

予想通り#oauth2.hasScope('admin')作品が、明らかに#id == authentication.principal.user_id"一部ではありません:たとえば、私は追加user_idデータを(それは春データ残りで使用するために春データJPAリポジトリである)を使用したいと思います。

式ベースのアクセス制御でトークンに追加された追加データにどのようにアクセスできますか?

答えて

5

私は自分自身を見つけました。主要なインターフェイスはUserAuthenticationConverterです。

デフォルトのDefaultUserAuthenticationConverterクラスを使用すると、を設定して、authentication.principalにUserDetailsS​​erviceから返されたUserDetailオブジェクトを設定することができます。それがなければ、authentication.principalはトークンusernameを文字列として設定するだけです。ここで

は私ResourceServerConfigAdapterの抽出物である:

@Configuration 
@EnableResourceServer 
protected static class ResourceServerConfiguration 
     extends ResourceServerConfigurerAdapter { 

    @Bean 
    UserDetailsService userDetailsService() { 
     return new UserDetailsServiceImpl(); 
    } 

    @Bean 
    public UserAuthenticationConverter userAuthenticationConverter() { 
     DefaultUserAuthenticationConverter duac 
      = new DefaultUserAuthenticationConverter(); 
     duac.setUserDetailsService(userDetailsService()); 
     return duac; 
    } 

    @Bean 
    public AccessTokenConverter accessTokenConverter() { 
     DefaultAccessTokenConverter datc 
      = new DefaultAccessTokenConverter(); 
     datc.setUserTokenConverter(userAuthenticationConverter()); 
     return datc; 
    } 

    @Bean 
    RemoteTokenServices getRemoteTokenServices() { 
     RemoteTokenServices rts = new RemoteTokenServices(); 
     rts.setCheckTokenEndpointUrl(
      "http://localhost:15574/oauth/check_token"); 
     rts.setAccessTokenConverter(accessTokenConverter()); 
     rts.setClientId("client"); 
     rts.setClientSecret("pass"); 
     return rts; 
    } 

    ... 

} 

もう一つの方法は、DefaultUserAuthenticationManagerをオーバーライドして、カスタムpublic Authentication extractAuthentication(Map<String, ?> map)を提供することです。

これが完了すると、我々はそのようなexpression-based access control上のユーザーデータを使用することができます。

@PreAuthorize("#oauth2.hasScope('admin') or #id == authentication.principal.userAccount.id") 
@Override 
UserAccount findOne (@P("id") Integer id); 

userAccountが私の元のドメインユーザーオブジェクトであること。 UserDetailsS​​erviceから返されるすべてのものになる可能性があります。

EDIT: バレンティンDespaに答えるために、ここに私のUserDetailsS​​erviceの実装は次のとおりです。共有のため

@Component 
public class UserDetailsServiceImpl implements UserDetailsService { 

    @Autowired 
    UserAccountRepository userAccountRepository; 

    public UserDetails loadUserByUsername (String username) 
      throws UsernameNotFoundException { 

     // Fetch user from repository 
     UserAccount ua = this.userAccountRepository 
      .findByEmail(username); 

     // If nothing throws Exception 
     if (ua == null) { 
      throw new UsernameNotFoundException(
       "No user found having this username"); 
     } 

     // Convert it to a UserDetails object 
     return new UserDetailsImpl(ua); 

    } 

} 
+0

感謝。 UserDetailsS​​erviceImplはどのように見えますか? –

+1

私は自分のUserDetailsS​​erviceImplを答えに加えました。 –

+0

速い返答をありがとう。 –

関連する問題