Собственный сервер 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
Фильтр до весны безопасности по умолчанию.