У меня толстое клиентское приложение (C #, но это не должно иметь значения).
Все пользователи уже существуют в системе аутентификации / авторизации (сторонней), которая предоставляет API OAuth 2 (authorize / access_token плюс сервис user_info).
У меня есть уровень веб-службы Spring Boot, который будет иметь веб-службы RESTful, которые будут вызываться приложением толстого клиента, которое должно вызываться только аутентифицированными пользователями для защищенных веб-служб.
Для аутентификации толстый клиент запустит веб-браузер (ОС установлена по умолчанию) и откроет https для restful.web.server: 8443 / login уровня веб-службы Spring Boot. Это сделает взаимодействие OAuth 2 (authorization_code). После перенаправления обратно с действительным токеном я хочу перенаправить на пользовательский URI, передающий токен, и закрыть браузер (если это возможно), чтобы приложение, зарегистрированное в ОС, могло извлечь токен и передать его через механизм IPC в приложение толстого клиента.
Приложение толстого клиента может затем передать токен веб-службам в заголовке (Authorize: TOKEN_TYPE TOKEN_VALUE).
Веб-службы должны затем проверить подлинность токена.
Веб-службы, вызываемые с недействительным токеном, должны просто возвращать ошибку HTTP и содержимое ошибки JSON (например, код + сообщение), а не пытаться перенаправить на экран входа в систему. Это будет организовано толстым клиентским приложением.
Я не имею никакого отношения к какой-либо пользовательской обработке URI, разработке IPC или вызовам веб-службы толстого клиента. Это все, что нужно для Spring / SSO, - получить токен для отправки моему толстому клиенту и вернуть соответствующую ошибку от защищенных веб-сервисов, не возвращая перенаправление на вход в SSO.
Кажется, я аутентифицируюсь и мне посылают токен, но затем я получаю исключение.
Я добился определенного прогресса, и похоже, что, запустив браузер вручную и перейдя на уровень моего веб-сервиса https to restful.web.server: 8443 / login, он перенаправляет на сайт SSO https на 3rdparty.sso.server / oauth / авторизация (передача client_id, redirect_uri, response_type = code, state). Я могу войти в систему, и Spring вызывает конечную точку https to 3rdparty.sso.server / oauth / access_token (мне пришлось создать пользовательский RequestEnhancer, чтобы добавить авторизацию: Basic ENCODED_CLIENT_ID_AND_CLIENT_SECRET для удовлетворения требованиям API-интерфейса SSO access_token).
Это возвращает 200 ОК, но потом я получаю исключения и не знаю, как извлечь токен. Возвращенный access_token может не использовать стандартные имена свойств, но не уверен, когда нужно идти и проверять, так ли это. Я сделал аутентификацию таким образом, чтобы сохранить идентификатор клиента и секрет клиента вне приложения толстого клиента, и мои веб-сервисы должны все равно выполнить авторизацию. Если есть лучший способ или указатели на то, чтобы кто-то уже делал это, это будет с благодарностью. Я нахожу так много примеров, которые либо не совсем актуальны, либо больше относятся к веб-приложениям.
server:
port: 8443
ssl:
key-store: classpath:keystore.p12
key-store-password: **********
keyStoreType: PKCS12
keyAlias: tomcat
servlet:
context-path: /
session:
cookie:
name: UISESSION
security:
basic:
enabled: false
oauth2:
client:
clientId: *******
clientSecret: *****************
accessTokenUri: https://3rdparty.sso.server/oauth2/access_token
userAuthorizationUri: https://3rdparty.sso.server/oauth2/authorize
authorizedGrantTypes: authorization_code,refresh_token
scope:
tokenName: accessToken
redirectUri: https://restful.web.server:8443/login
authenticationScheme: query
clientAuthenticationScheme: header
resource:
userInfoUri: https://3rdparty.sso.server/oauth2/userinfo
logging:
level:
org:
springframework: DEBUG
spring:
http:
logRequestDetails: true
logResponseDetails: true
@Configuration
@EnableOAuth2Sso
@Order(value=0)
public class ServiceConectWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter
{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// From the root '/' down...
.antMatcher("/**")
// requests are authorised...
.authorizeRequests()
// ...to these url's...
.antMatchers("/", "/login**", "/debug/**", "/webjars/**", "/error**")
// ...without security being applied...
.permitAll()
// ...any other requests...
.anyRequest()
// ...the user must be authenticated.
.authenticated()
.and()
.formLogin().disable()
.logout()
.logoutSuccessUrl("/login")
.permitAll()
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
;
}
Я ожидаю, что защищенные веб-службы будут доступны после проверки подлинности через браузер во время тестирования без клиента и не будут ожидать появления исключений. Мне нужно иметь возможность извлечь возвращенный токен и передать его моему толстому клиенту.
Redirects to 'https://3rdparty.sso.server/oauth2/authorize?client_id=***HIDDEN_CLIENT_ID***&redirect_uri=https://localhost:8443/login&response_type=code&state=***HIDDEN_STATE_1***'
Then FilterChainProxy : /login?code=***HIDDEN_CODE_1***&state=***HIDDEN_STATE_1*** at position 6 of 12 in additional filter chain;
Request is to process authentication
RestTemplate : HTTP POST https://3rdparty.sso.server/oauth2/access_token
RestTemplate : Response 200 OK
IllegalStateException: Access token provider returned a null access token, which is illegal according to the contract.
at OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:223) ```
Then end up at an error page
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
There was an unexpected error (type=Internal Server Error, status=500).
Access token provider returned a null access token, which is illegal according to the contract.