26

@EnableResourceServerアノテーションで構成されたリソースサーバーがあり、user-info-uri次のようにパラメーターを介して承認サーバーを参照します。

security:
  oauth2:
    resource:
      user-info-uri: http://localhost:9001/user


承認サーバー/ユーザー エンドポイントは、org.springframework.security.core.userdetails.Userたとえば電子メールを含む拡張子を返します。

{  
   "password":null,
   "username":"myuser",
    ...
   "email":"me@company.com"
}


一部のリソース サーバー エンドポイントにアクセスするたびに、Spring は承認サーバーのエンドポイントを呼び出してバックグラウンドでアクセス トークンを検証し、/user実際に強化されたユーザー情報を取得します (メール情報などを含む、Wireshark で検証済み)。

/userしたがって、問題は、承認サーバーのエンドポイントへの明示的な 2 回目の呼び出しを行わずに、このカスタム ユーザー情報を取得するにはどうすればよいかということです。Spring は承認後にリソース サーバーのどこかにローカルに保存しますか、それともすぐに利用できるものが何もない場合にこの種のユーザー情報保存を実装する最良の方法は何ですか?

4

6 に答える 6

24

解決策は、カスタムの実装ですUserInfoTokenServices

https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/UserInfoTokenServices.java

カスタム実装を Bean として提供するだけで、デフォルトの代わりに使用されます。

この UserInfoTokenServices 内で、必要に応じて構築できprincipalます。

/usersこの UserInfoTokenServices は、認可サーバーのエンドポイントの応答から UserDetails を抽出するために使用されます。ご覧のとおり

private Object getPrincipal(Map<String, Object> map) {
    for (String key : PRINCIPAL_KEYS) {
        if (map.containsKey(key)) {
            return map.get(key);
        }
    }
    return "unknown";
}

で指定されたプロパティのみがPRINCIPAL_KEYSデフォルトで抽出されます。そして、それはまさにあなたの問題です。ユーザー名やプロパティの名前だけでなく、それ以上のものを抽出する必要があります。そのため、さらにキーを探します。

private Object getPrincipal(Map<String, Object> map) {
    MyUserDetails myUserDetails = new myUserDetails();
    for (String key : PRINCIPAL_KEYS) {
        if (map.containsKey(key)) {
            myUserDetails.setUserName(map.get(key));
        }
    }
    if( map.containsKey("email") {
        myUserDetails.setEmail(map.get("email"));
    }
    //and so on..
    return myUserDetails;
}

配線:

@Autowired
private ResourceServerProperties sso;

@Bean
public ResourceServerTokenServices myUserInfoTokenServices() {
    return new MyUserInfoTokenServices(sso.getUserInfoUri(), sso.getClientId());
}

!!Spring Boot 1.4 での更新が簡単になりました!!

Spring Boot 1.4.0 では、PrincipalExtractorが導入されました。このクラスは、カスタム プリンシパルを抽出するために実装する必要があります ( Spring Boot 1.4 リリース ノートを参照)。

于 2016-01-29T19:31:19.347 に答える
1

JWT トークンを使用できます。すべてのユーザー情報が保存されるデータストアは必要ありません。代わりに、追加情報をトークン自体にエンコードできます。トークンがデコードされると、アプリは Principal オブジェクトを使用してこのすべての情報にアクセスできるようになります

于 2016-01-29T02:42:46.943 に答える