2015-11-19 13 views
9

私は春のセキュリティモジュールでOAuth2パスワードの付与を実装しました。 UserDetailsとUserDetailsS​​ervice(jdbc)の独自の実装を追加します。私はあなたのコントローラーに私のコントローラーに次のものを書き込んでいます:Spring Oauth2 - リロードプリンシパル

@AuthenticationPrincipal User user 

ここで、ユーザーは私のUserDetailsの実装です。 トークンを更新せずにユーザーデータを変更する可能性を追加します。

私はプリンシパルを更新しよう:

User updatedUser = ... 
Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities()); 
SecurityContextHolder.getContext().setAuthentication(newAuth); 

しかし、私はそれが古いUserオブジェクトを返す別のコントローラメソッドを呼び出すときには、動作しません。

トークンを更新せずにユーザーデータを変更する方法はありますか?春のセキュリティを常にキャッシュからではなく、データベースからロードするソリューションはありますか?

+0

を設定するには、あなたのコードは、あなたは、プリンシパルを更新していますか? –

答えて

2

私はthis answerからこれを達成する方法を見つけました。私は

@Bean 
public ReloadUserPerRequestHttpSessionSecurityContextRepository userDetailContextRepository() { 
    return new ReloadUserPerRequestHttpSessionSecurityContextRepository(); 
} 

HttpSessionSecurityContextRepositoryを作成し、すべてのリクエストで更新されたユーザ情報を取得するために

.and() 
     .csrf() 
      .csrfTokenRepository(csrfTokenRepository()) 
    .and() 
     .securityContext() 
      .securityContextRepository(userDetailContextRepository()) 
以下

あるサンプルコードとしてWebSecurityConfigurerAdapterのクラスから私のHttpSecurityにこれを追加します。 APIサーバーから、またはoauth2構成のuser-info-urlからフェッチできます。

public class ReloadUserPerRequestHttpSessionSecurityContextRepository extends HttpSessionSecurityContextRepository { 

    @Override 
    public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) { 
     SecurityContext context = super.loadContext(requestResponseHolder); 

     Authentication auth = context.getAuthentication(); 
     if (auth != null && auth instanceof OAuth2Authentication) { 
      OAuth2Authentication oldAuth = (OAuth2Authentication) auth; 
      if (oldAuth.getPrincipal() instanceof LinkedHashMap) { 
       createNewUserDetailsFromPrincipal(oldAuth.getPrincipal()); 
      } 
      context.setAuthentication(oldAuth); 
     } 
     return context; 
    } 

    @SuppressWarnings("unchecked") 
    private void createNewUserDetailsFromPrincipal(Object principal) { 
     LinkedHashMap<String, Object> userDetailInfo = (LinkedHashMap<String, Object>) principal; 
     // fetch User informations from your API server or your database or 
     // 'user-info-url' of oauth2 endpoint 
     userDetailInfo.put("name", "EDITED_USER_NAME"); 
    } 

} 
1

これは単なる推測ですが、SecurityContextもクリアする必要があると思います。

SecurityContextHolder.clearContext();との最初の明確なセキュリティコンテキスト、アプリケーションのどの層で認証

Authentication newAuth = new UsernamePasswordAuthenticationToken(updatedUser, updatedUser.getPassword(), updatedUser.getAuthorities()); 
SecurityContextHolder.getContext().setAuthentication(newAuth); 
+0

アプリケーションこれらはOauth2によって保護されており、 'UsernamePasswordAuthenticationToken'型認証を割り当てることはできません。 – Cataclysm

関連する問題