Я пытаюсь подключить авторизацию OAuth к своему проекту через Github, но после успеха мой пользователь остается анонимным:
@RestController
@RequestMapping(path = "/")
public class HomeController {
@GetMapping
public String home() {
return "Hello, %s".formatted(SecurityContextHolder.getContext().getAuthentication().getName());
}
}
и вывод:
Hello, anonymousUser
Вот мой компонент SecurityFilterChain и настройки application.yaml:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, Converter<Jwt, UsernamePasswordAuthenticationToken> converter) throws Exception {
http
.authorizeHttpRequests(authorize ->
authorize
.anyRequest()
.permitAll()
)
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.oauth2Login(withDefaults())
.oauth2ResourceServer(configurer ->
configurer
.jwt((jwt) -> jwt.jwtAuthenticationConverter(converter))
)
.sessionManagement(configurer ->
configurer
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.exceptionHandling(configurer ->
configurer
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
.accessDeniedHandler(new BearerTokenAccessDeniedHandler())
);
return http.build();
}
spring:
security:
oauth2:
client:
registration:
github:
clientId: <hidden>
clientSecret: <hidden>
redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'
УПД: Я так понял, что это происходит из-за настроек:
.sessionManagement(configurer ->
configurer
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
, но я не понимаю, как это отключить? Я хочу, чтобы в моем приложении не было сеансов и общение осуществлялось исключительно через токены доступа, выданные Github, но вместо этого я получаю JSESSIONID, установленный в файле cookie. Как сделать так, чтобы после успешной авторизации возвращались токены доступа вместо установки Cookies?




Где и как вы ожидаете хранить токены между запросами? Вы ничего не кодировали, чтобы предоставить интерфейсу токены, которые ваш клиент Spring OAuth2 получает с помощью потока кода авторизации.
Вероятно, вам следует прочитать раздел Основы OAuth2 моих руководств.
oauth2Login (код авторизации и токены обновления в клиенте Spring OAuth2) — это что-то:
Сервер авторизации, клиент и сервер ресурсов — это три разных субъекта OAuth2. Авторизация запросов на основе Bearer токена доступа — это бизнес сервера ресурсов => oauth2Login не имеет никакого отношения к серверу ресурсов.
В качестве примечания: если ваш интерфейс представляет собой одностраничное или мобильное приложение, вам не следует пытаться авторизовать свои запросы с помощью токенов Bearer . Вместо этого вам следует использовать сеансы на бэкэнде OAuth2 для фронтенда.
Я, наверное, неправильно понял ваш вопрос. У меня есть мобильное приложение, которое взаимодействует с REST API. Я хочу сохранить токен в мобильном приложении.
Если вас интересует, почему вам следует использовать сеансы между интерфейсом и сервером, вы можете прочитать этот пост от команды Spring Security: github.com/spring-projects/spring-authorization-server/issues/…
Я обменял код авторизации на токен. Ты этого не сделал. Ваш клиент Spring OAuth2 сделал это на сервере. Вы ничего не кодировали для сервера для отправки токена в мобильный интерфейс, а также для этого интерфейса для хранения токенов, предоставления токена доступа в качестве заголовка авторизации Bearer для следующих запросов к серверу или обновления токена доступа по истечении срока его действия с использованием токена обновления, обычно примерно каждые 5 минут. И в любом случае вам не следует пытаться отправлять токены во фронтенд. Просто научитесь работать с сессиями между фронт-эндом и бэк-эндом.
Отлично. Я понял, что этот стандарт предполагает использование сессий. Остается еще один вопрос: допустима ли практика получать информацию о пользователе от стороннего сервиса и выпускать на ее основе собственный токен JWT? Чтобы избавить пользователя от необходимости регистрироваться и подтверждать телефон или электронную почту, но не более того.
Это делает любой сервер авторизации, соответствующий OIDC (Keycloak, Auth0, Spring Authorization Server и многие другие).
этот стандарт предполагает использование сеансов. Это справедливо только для сервера авторизации и серверных клиентов, а не для серверов ресурсов, которые могут (и должны) быть без сохранения состояния.
Почему мне следует хранить токен JWT? Смысл токена не в том, чтобы их хранить. А разве нет? Я связался с Github, перенаправил пользователя, он залогинился, а затем я обменял код авторизации на токен. Могу ли я просто передать этот токен интерфейсу, а затем он будет взаимодействовать с сервером, просто поместив его в заголовок авторизации?