Spring Security OAuth2 с несколькими IDP и формой входа: соответствующие пользователи - PullRequest
0 голосов
/ 06 марта 2019

Я использовал Spring Security несколько раз в нескольких проектах, включая трехстороннюю аутентификацию OAuth2 на Zuul API Gateway и т. Д. Все отлично работает, а официальная документация очень аккуратна и проста.

Но есть один момент, который я до сих пор не понял из документов. Представьте, что у вас есть Ресурсный сервер на основе пружин с несколькими поставщиками идентификаторов , а также у вас есть собственная база данных пользователей и форма входа в систему.

Таким образом, пользователи могут проходить аутентификацию либо через регистрационную форму, либо через одного из IDP (скажем, Google или Facebook).

Вопрос в том, как сопоставить Аутентификацию от любого из ваших ВПЛ с объектом Аутентификации, который улучшен / сопоставлен с вашим локальным пользователем?

Т.е.: Алиса имеет учетную запись в вашей системе (в вашей базе данных). Она заходит в свой «профиль» и заявляет, что у нее также есть учетная запись Google или Facebook. Хорошо, готово, вы сохранили эту информацию где-то в вашей системе.

Теперь, когда Алиса входит в вашу систему через социальную сеть, какой весенний API вы используете, чтобы понять, что Алиса, введенная через Google, - это та же Алиса, которая уже зарегистрирована в вашей БД? В каком API вы повышаете ее Аутентификацию с полномочиями на основе вашей БД?

Заранее спасибо, ребята

1 Ответ

1 голос
/ 06 марта 2019

Обычно это делается путем создания составного объекта, который содержит как объект OidcUser, так и объект вашего домена. Например:

@Component
public class MyOAuth2UserService implements OAuth2UserService<OidcUserRequest, OidcUser> {
    private final OidcUserService delegate = new OidcUserService();

    @Override
    public OidcUser loadUser(OidcUserRequest oidcUserRequest) {
        // the information that comes back from google, et al
        OidcUser oidcUser = this.delegate.loadUser(oidcUserRequest);

        // the information from your DB
        MyUser user = this.myRepository.findUserByXYZ(oidcUser.getXYZ());

        return new MyOidcUser(user, oidcUser);
    }

    private static class MyOidcUser extends MyUser implements OidcUser {
        private final OidcUser delegate;

        public MyOidcUser(MyUser user, OidcUser oidcUser) {
            super(user);
            this.delegate = oidcUser;
        }

        // ... implement delegate methods
    }
} 

Обратите внимание, что XYZ - это некоторый атрибут, который позволяет вам знать, что пользователь из Google является пользователем из вашей системы. Может быть, это адрес электронной почты, например.

Преимущество этой дополнительной работы заключается в том, что Spring Security поместит этот MyOidcUser объект в Authentcation#getPrincipal. Так что теперь, если вам нужно получить биты вашего домена, вы делаете (MyUser) authentication.getPrincipal(), но если вам нужны биты OIDC, вы делаете (OidcUser) authentication.getPrincipal(). В зависимости от ваших вариантов использования вы можете сделать что-то простое:

@GetMapping("/endpoint1")
public String endpoint1(@AuthenticationPrincipal MyUser myUser) {
    // ...
}

@GetMapping("/endpoint2")
public String endpoint2(@AuthenticationPrincipal OidcUser oidcUser) {
    URL issuer = oidcUser.getIdToken().getIssuer();
    // ...
}
...