1. Обзор
В этом руководстве мы узнаем , как использовать Spring OAuth2RestTemplate
для выполнения вызовов REST OAuth2 .
Мы создадим веб-приложение Spring, способное отображать репозитории учетной записи GitHub.
2. Конфигурация Maven
Во- первых, нам нужно добавить зависимости spring-boot-starter-security и spring-security-oauth2-autoconfigure в наш pom.xml
. Поскольку мы создаем веб-приложение, нам также необходимо включить артефакты spring-boot-starter-web и spring-boot-starter-thymeleaf .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
3. Свойства OAuth2
Далее давайте добавим конфигурацию OAuth в наш файл application.properties
, чтобы можно было подключить учетную запись GitHub:
github.client.clientId=[CLIENT_ID]
github.client.clientSecret=[CLIENT_SECRET]
github.client.userAuthorizationUri=https://github.com/login/oauth/authorize
github.client.accessTokenUri=https://github.com/login/oauth/access_token
github.client.clientAuthenticationScheme=form
github.resource.userInfoUri=https://api.github.com/user
github.resource.repoUri=https://api.github.com/user/repos
Обратите внимание, что нам нужно заменить [
CLIENT_ID]
и [CLIENT_SECRET]
значениями из приложения GitHub OAuth. Мы можем следовать руководству по созданию приложения OAuth , чтобы зарегистрировать новое приложение на GitHub:
Давайте удостоверимся, что для URL-адреса обратного вызова авторизации установлено значение http://localhost:8080,
что перенаправит поток OAuth на домашнюю страницу нашего веб-приложения.
4. Конфигурация шаблона OAuth2Rest
Теперь пришло время создать конфигурацию безопасности, чтобы предоставить нашему приложению поддержку OAuth2.
4.1. Класс SecurityConfig
_
Во-первых, давайте расширим WebSecurityConfigurerAdapter
, чтобы воспользоваться помощниками конфигурации Spring:
@Configuration
@EnableOAuth2Client
public class SecurityConfig extends WebSecurityConfigurerAdapter {
OAuth2ClientContext oauth2ClientContext;
public SecurityConfig(OAuth2ClientContext oauth2ClientContext) {
this.oauth2ClientContext = oauth2ClientContext;
}
...
}
@EnableOAuth2Client
дает нам доступ к контексту OAuth2, который мы будем использовать для создания нашего OAuth2RestTemplate
.
4.2. Бин OAuth2RestTemplate
Во-вторых, мы создадим bean-компонент для нашего OAuth2RestTemplate
:
@Bean
public OAuth2RestTemplate restTemplate() {
return new OAuth2RestTemplate(githubClient(), oauth2ClientContext);
}
@Bean
@ConfigurationProperties("github.client")
public AuthorizationCodeResourceDetails githubClient() {
return new AuthorizationCodeResourceDetails();
}
При этом мы используем свойства и контекст OAuth2 для создания экземпляра шаблона.
Аннотация @ConfigurationProperties
внедряет все свойства github.client
в экземпляр AuthorizationCodeResourceDetails .
4.3. Фильтр аутентификации
В-третьих, нам нужен фильтр аутентификации для обработки потока OAuth2:
private Filter oauth2ClientFilter() {
OAuth2ClientAuthenticationProcessingFilter oauth2ClientFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github");
OAuth2RestTemplate restTemplate = restTemplate();
oauth2ClientFilter.setRestTemplate(restTemplate);
UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), githubClient().getClientId());
tokenServices.setRestTemplate(restTemplate);
oauth2ClientFilter.setTokenServices(tokenServices);
return oauth2ClientFilter;
}
@Bean
@ConfigurationProperties("github.resource")
public ResourceServerProperties githubResource() {
return new ResourceServerProperties();
}
Здесь мы указываем фильтру инициировать поток OAuth2 по URL-адресу /login/github
нашего приложения.
4.4. Конфигурация безопасности Spring
Наконец, давайте зарегистрируем OAuth2ClientContextFilter
и создадим конфигурацию веб-безопасности:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/login**", "/error**")
.permitAll().anyRequest().authenticated()
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/")
.and().addFilterBefore(oauth2ClientFilter(), BasicAuthenticationFilter.class);
}
@Bean
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(filter);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
return registration;
}
Мы защищаем пути наших веб-приложений и гарантируем, что OAuth2ClientAuthenticationProcessingFilter
зарегистрирован перед BasicAuthenticationFilter
.
5. Использование шаблона OAuth2RestTemplate
Основная цель OAuth2RestTemplate
— сократить объем кода, необходимого для выполнения вызовов API на основе OAuth2 . Это в основном удовлетворяет две потребности для нашего приложения:
- Обрабатывает поток аутентификации OAuth2.
- Расширяет Spring
RestTemplate
для выполнения вызовов API
Теперь мы можем использовать OAuth2RestTemplate
в качестве автоматически подключаемого компонента в веб-контроллере.
5.1. Авторизоваться
Давайте создадим файл index.html
с параметрами входа и дома:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>OAuth2Client</title>
</head>
<body>
<h3>
<a href="/login/github" th:href="@{/home}" th:if="${#httpServletRequest?.remoteUser != undefined }">
Go to Home
</a>
<a href="/hello" th:href="@{/login/github}" th:if="${#httpServletRequest?.remoteUser == undefined }">
GitHub Login
</a>
</h3>
</body>
</html>
Пользователям, не прошедшим проверку подлинности, будет предоставлена возможность входа в систему, а пользователи, прошедшие проверку подлинности, могут получить доступ к домашней странице.
5.2. Дом
Теперь давайте создадим контроллер для приветствия аутентифицированного пользователя GitHub:
@Controller
public class AppController {
OAuth2RestTemplate restTemplate;
public AppController(OAuth2RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/home")
public String welcome(Model model, Principal principal) {
model.addAttribute("name", principal.getName());
return "home";
}
}
Обратите внимание, что у нас есть параметр безопасности Principal
в методе приветствия .
Мы используем имя принципала
в качестве атрибута модели пользовательского интерфейса.
Давайте посмотрим на шаблон home.html
:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home</title>
</head>
<body>
<p>
Welcome <b th:inline="text"> [[${name}]] </b>
</p>
<h3>
<a href="/repos">View Repositories</a><br/><br/>
</h3>
<form th:action="@{/logout}" method="POST">
<input type="submit" value="Logout"/>
</form>
</body>
</html>
Кроме того, мы добавляем ссылку для просмотра списка репозиториев пользователя и возможность выхода из системы.
5.3. Репозитории GitHub
Теперь пришло время использовать шаблон OAuth2RestTemplate,
созданный в предыдущем контроллере, для представления всех репозиториев GitHub, принадлежащих пользователю.
Во-первых, нам нужно создать класс GithubRepo
для представления репозитория:
public class GithubRepo {
Long id;
String name;
// getters and setters
}
Во-вторых, давайте добавим сопоставление репозиториев с предыдущим AppController
:
@GetMapping("/repos")
public String repos(Model model) {
Collection<GithubRepo> repos = restTemplate.getForObject("https://api.github.com/user/repos", Collection.class);
model.addAttribute("repos", repos);
return "repositories";
}
OAuth2RestTemplate обрабатывает весь
шаблонный код для выполнения запроса к GitHub . Кроме того, он преобразует ответ REST в коллекцию GithubRepo
.
Наконец, давайте создадим шаблон repositories.html
для перебора коллекции репозиториев:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Repositories</title>
</head>
<body>
<p>
<h2>Repos</h2>
</p>
<ul th:each="repo: ${repos}">
<li th:text="${repo.name}"></li>
</ul>
</body>
</html>
6. Заключение
В этой статье мы узнали, как использовать OAuth2RestTemplate
для упрощения вызовов REST к серверу ресурсов OAuth2, такому как GitHub.
Мы рассмотрели строительные блоки веб-приложения, использующего поток OAuth2. Затем мы увидели, как сделать вызов REST API для получения всех пользовательских репозиториев GitHub.
Как всегда, полный пример этого руководства можно найти на GitHub .