#spring-session #spring-security-rest
Вопрос:
Проблема: Мое приложение java springboot получает токен JWT от внешней системы для аутентификации пользователя с помощью внешнего поставщика управления идентификацией, который возвращает сведения о пользователе при успешном выполнении. После получения сведений о пользователях серверное приложение должно создать URL-адрес перенаправления для конечного пользователя внешней системы. URL-адрес перенаправления приведет пользователя в мое приложение angular, чтобы показать целевую страницу. Здесь все остальные API должны быть разрешены через сеанс http. В случае, если пользователь попытается получить прямой доступ к API rest, он должен получить сообщение об ошибке аутентификации.
Как мы можем добиться авторизации в этом случае, поскольку аутентификация не была выполнена моим приложением spring boot. Можем ли мы создать пользовательский весенний сеанс с помощью spring security и вручную поместить учетные записи пользователей в контекст безопасности?
Ответ №1:
В настоящее время я занимаюсь токенами JWT, полученными от Google. Включая Google, почти все серверы авторизации предоставляют API-интерфейсы rest , такие как GET /userInfo
, где вы можете указать токен JWT в заголовке запроса или в URL-адресе в качестве параметра GET, а затем проверить, является ли токен JWT действительным, не истекшим и т. Д.
Поскольку проверка токена JWT обычно не имеет состояния, эти API, как правило, имеют большой лимит, и вы можете вызывать их столько раз, сколько вам нужно.
Я предполагаю, что у вас интегрирована система безопасности Spring, а затем вы можете добавить фильтр. Таким образом, каждый запрос должен быть проверен на наличие его маркера в заголовке.
@Service
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
String header = request.getHeader("Authorization");
RestTemplate restTemplate = new RestTemplate(); // If you use Google SDK, xxx SDK, you do not have to use restTemplate
String userInfoUrl = "https://example.com/api/userInfo";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", header);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<String> response = restTemplate.exchange(
userInfoUrl, HttpMethod.GET, entity, String.class, param);
User user = response.getBody(); // Get your response and figure out if the Token is valid.
// If the token is valid? Check it here....
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception ex) {
logger.error("Could not set user authentication in security context", ex);
}
filterChain.doFilter(request, response);
}
}