Собственный сервер Spring OAuth2 вместе с 3-сторонними поставщиками OAuth

В приложении Spring Boot у меня есть серверы OAuth2 Authorization\Resource. Исходя из этого и Spring Security, я защитил конечные точки REST API Spring MVC.

В дополнение к этому, я хотел бы также добавить аутентификацию для моих конечных точек REST на основе сторонних поставщиков OAuth, таких как Twitter, Facebook, Google.

В моем приложении у меня есть две сущности - User а также SocialUser, SocialUser представляет профиль пользователя в социальных сетях. User может иметь 0-* связанный SocialUsers, Прямо сейчас я могу аутентифицировать пользователя в Твиттере, и после этого я создаю две записи в своей базе данных - User и SocialUser. SocialUser содержит токены доступа / обновления, выпущенные Twitter, и некоторую другую информацию профиля из этой социальной сети.

Сейчас я не знаю, как связать этого пользователя, созданного из социальной сети, с моим существующим потоком аутентификации \ авторизации. Для этого пользователя я хотел бы создать свой собственный (на моем собственном сервере авторизации OAuth2) accessToken и предоставить его клиенту.

Кроме того, у этого пользователя нет имени пользователя, пароля и адреса электронной почты в его User юридическое лицо. А также я не знаю, как вручную создать свой собственный токен доступа и отправить его клиенту для будущих вызовов API.

Я нашел несколько примеров:

@Inject
private TokenEndpoint tokenEndpoint;

public String createAccessToken(User user) {
    HashMap<String, String> parameters = new HashMap<String, String>();
    parameters.put("client_id", "appid");
    parameters.put("client_secret", "myOAuthSecret");
    parameters.put("grant_type", "password");
    parameters.put("password", user.getPassword());
    parameters.put("scope", "read write");
    parameters.put("username", user.getUsername());

    // principal ??
    return tokenEndpoint.getAccessToken(principal, parameters);
}

но я не знаю, как создать Principal основываясь на моем User юридическое лицо, а также я теперь уверен, что это правильный путь..

Итак, главный вопрос - как вручную сгенерировать этот новый токен через мой собственный сервер OAuth для этого нового пользователя?

Посоветуйте, пожалуйста, как это можно правильно реализовать. Благодарю.

ОБНОВЛЕНО:

я добавил ProviderSignInController в мое приложение и возможность прямо сейчас исполнить полный танец OAuth с Twitter. Кроме того, я реализовал свой собственный Neo4jConnectionRepository а также Neo4jUsersConnectionRepository потому что я использую Neo4j в качестве основной базы данных.

@Bean
public ProviderSignInController providerSignInController() {
    return new ProviderSignInController(socialAuthenticationServiceLocator, usersConnectionRepository, new SignInAdapter() {

        @Override
        public String signIn(String userId, Connection<?> connection, NativeWebRequest request) {
            System.out.println("User ID: " + userId + " social display name: " + connection.getDisplayName());
            return null;
        }
    });
}

Пока все работает хорошо.

Один вопрос - как аутентифицировать / авторизовать User через мой собственный сервер авторизации OAuth2 в SignInAdapter.signIn метод?

Я думаю, что мне нужно создать OAuth2Authentication объект для этого пользователя и поместить его в контекст безопасности.. Я прав? Если да, не могли бы вы показать мне пример, как это можно реализовать?

2 ответа

Решение

Итак, чего вы хотите добиться: когда клиенты перенаправляют пользователей на ваш сервер авторизации (код авторизации или неявное предоставление), чтобы получить токен, пользователь может войти в систему, используя свою любимую социальную сеть.

Если я правильно понимаю, вы свернули свою собственную реализацию единого входа (SSO) с Twitter (ProviderSignInController), и теперь вы задаетесь вопросом, как генерировать токен, когда Twitter отвечает "ОК".

Я думаю, что вы взяли проблему не с того конца: вместо того, чтобы создавать свой клиент Twitter и программно генерировать токен, идея состоит в том, чтобы интегрировать социальный SSO в поток spring-security-oauth2, который в действительности заключается в том, как интегрировать социальный SSO в Весенняя безопасность.

В конце концов, речь идет о том, как ваш сервер авторизации защищает AuthorizationEndpoint: /oauth/authorize, Поскольку ваш сервер авторизации работает, у вас уже есть класс конфигурации, расширяющий WebSecurityConfigurerAdapter который занимается безопасностью для /oauth/authorize с formLogin, Вот где вам нужно интегрировать социальные вещи.

Вместо использования встроенного механизма проверки подлинности формы Spring Security вам придется подключить собственную защиту, которая либо позволяет пользователю войти в систему с помощью формы, либо запускает SSO с другими провайдерами.
Spring Security состоит из множества абстракций, но на самом деле все сводится к заполнению SecurityContext с Authentication Объект для каждого запроса.

Как только процесс аутентификации завершится, пользователь продолжит /oauth/authorizeдайте согласие на доступ клиента к некоторым областям, и токен будет доставлен, как обычно, без необходимости генерировать токены программным путем.

Я сделал это, используя SAML (расширение SAML Spring Security), но в вашем случае вам стоит покопаться в проектах Spring Social, которые, кажется, поддерживают все основные социальные сети из коробки.
Хорошая новость в том, что у вас уже есть куча доступных инструментов, "плохие новости" в том, что вам нужно будет понять, как они работают в определенной степени, чтобы соединить их вместе.

Из этого туториала вы узнаете, как именно этого добиться (если я правильно понял проблему): иметь сервер авторизации, выдающий свои собственные токены oauth2 на основе внешней аутентификации oauth2. Соответствующий код доступен здесь.

Суть в том, что вы используете @EnableOAuth2Client в дополнение к @EnableAuthorizationServer и вставьте OAuth2ClientAuthenticationProcessingFilter Фильтр до весны безопасности по умолчанию.

Другие вопросы по тегам