#java #spring-boot #postman #keycloak
Вопрос:
Я пытаюсь подключить RestAPI, созданный с помощью SpringBoot, чтобы получить маркер доступа из маскировки ключей.
Это код, который у меня есть:
Приложение.yml
keycloak:
realm: ${CLIENT_RELM_NAME:registerApiRealm}
auth-server-url: ${KEYCLOAK_URL_WITH_PATH:http://localhost:8080/auth}
ssl-required: external
#keycloak resource is the client ID
resource: ${KEYCLOAK_CLIENT_NAME:registerApiClienty}
#replace secret with your key
credentials:
secret: ${CLIENT_RELM_SECRET:12a658ea-b728-4f53-9948-492ef470363f}
#The line below will prevent redirect to login page
bearer-only: true
KeycloakServiceImpl.java
@Component
public class KeyCloakServiceImpl implements KeyCloakService {
private static final Logger log = LoggerFactory.getLogger(RegistrationController.class);
@Value("${keycloak.credentials.secret}")
private String SECRETKEY;
@Value("${keycloak.resource}")
private String CLIENTID;
@Value("${keycloak.auth-server-url}")
private String AUTHURL;
@Value("${keycloak.realm}")
private String REALM;
@Value("${admin.username}")
private String ADMIN_USERNAME;
@Value("${admin.password}")
private String ADMIN_PASSWORD;
@Autowired
RestTemplate restTemplate;
@Override
public TokenDto getToken(UserCredentials userCredentials) {
TokenDto responseToken = null;
try {
MultiValueMap<String, String> urlParameters = new LinkedMultiValueMap<>();
urlParameters.add("grant_type", "password");
urlParameters.add("client_id", CLIENTID);
urlParameters.add("username", userCredentials.getUsername());
urlParameters.add("password", userCredentials.getPassword());
urlParameters.add("client_secret", SECRETKEY);
responseToken = authenticate(urlParameters);
} catch (Exception e) {
e.printStackTrace();
}
return responseToken;
}
private TokenDto authenticate( MultiValueMap<String, String> urlParameters ) throws Exception {
TokenDto tokenDto = new TokenDto();
String uri = AUTHURL "/realms/" REALM "/protocol/openid-connect/token";
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(urlParameters, httpHeaders);
ResponseEntity<Object> result = restTemplate.exchange(uri, HttpMethod.POST, request, Object.class);
log.info("{}", result);
log.info("{}", result.getBody());
LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) result.getBody();
if (map != null) {
tokenDto.setAccess_token(map.get("access_token").toString());
tokenDto.setToken_type(map.get("token_type").toString());
tokenDto.setRefresh_token(map.get("refresh_token").toString());
tokenDto.setExpires_in(map.get("expires_in").toString());
tokenDto.setScope(map.get("scope").toString());
} else {
return null;
}
return tokenDto;
}
Когда я проверяю его с Postaman
помощью отправки username
и`пароля»
{
"username": "user",
"password": "useruser35"
}
Я получаю следующую ошибку:
org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: [{"error":"invalid_client","error_description":"Invalid client credentials"}]
Я не уверен, почему я дважды проверил, создан ли мой пользователь, и это так, я проверил идентификатор клиента и секрет, и все кажется прекрасным.
Чего мне здесь не хватает, буду признателен за любой совет.
Ответ №1:
Ваш код, похоже, действителен.
Возможно, вам захочется ознакомиться с этим руководством, чтобы узнать, правильно ли настроен ключ.
Поток предоставления пароля в вашем примере обычно не является предпочтительным подходом для входа в систему. Вы также можете получить токен с помощью spring security, см. Эту ссылку. В Интернете есть много примеров того, как сделать OAuth2 с помощью spring security.