2015-02-02 6 views
2

У меня есть Spring api, который защищен с использованием проверки подлинности base64 через базу данных. Можно ли затем взять еще один апри и каким-то образом пройти аутентификацию через первый апи?Аутентификация Spring Rest API через другой API REST

+0

Кстати, бэкенд использует UserDetailsService –

+0

почему бы не использовать OAuth? Это более безопасный способ, чем базовая аутентификация HTTP. Вот сообщение в блоге, которое может помочь. https://stormpath.com/blog/secure-your-rest-api-right-way/ – Alex

ответ

0

Base64 - это механизм кодирования, а не схема аутентификации. Я предполагаю, что вы имеете в виду, что используете basic authentication, который является именем пользователя и паролем base64, закодированным в HTTP-заголовке Authorization.

Если другая служба также использует базовую аутентификацию и проверяет имя пользователя и пароль на одну и ту же базу данных учетных данных, вы сможете использовать одну и ту же строку с кодировкой base64 для аутентификации против другой службы REST.

0

Все, что мне нужно было сделать, это иметь класс в моем втором API, который ловит все запросы, вызывая первый API, у которого уже есть соединение с моей базой данных, отправка основного заголовка проверки подлинности для проверки учетных данных.

5

Рассматривали ли вы защиту своих API с помощью аутентификации на основе OAuth и управления ключами API. HTTP Basic аутентификация не считает идеальной из и имени пользователя и пароля security perspective имеет другой набор security issues for APIs

В любом случае, вы можете рассмотреть возможность использования Stormpath сделать это очень легко для вас. Взгляните на this guide, он поддерживает как HTTP basic, так и OAuth.

Этот образец кода даст вам хорошее представление о том, насколько это просто.

Предположим, вы хотите открыть операцию под названием startEngines() и хотите ее защитить. Вам также необходимо будет открыть новую операцию, чтобы получить токены доступа, в этом примере String getAccessToken(ApiKey).

Ваши пользователи будут запускать что-то вроде этого:

@Test 
public void executeSomeOauth2AuthenticatedOperation() { 

    String userApiKeyPath = System.getProperty("user.home") + "/.stormpath/apiKey_4Yrc0TJ5sBFldwtu6nfzf5.properties"; 
    ApiKey userApiKey = ApiKeys.builder().setFileLocation(userApiKeyPath).build(); 

    //Developer requests access token 
    String accessToken = getAccessToken(userApiKey); 

    //Developer executes an authenticated operation (e.g startEngines()) with the provided accessToken 
    if (startEngines(accessToken)) { 
     System.out.print("Client-side message: Execution allowed"); 
    } else { 
     System.out.print("Client-side message: Execution denied"); 
    } 
} 

Ваш код будет выглядеть следующим образом:

String path = System.getProperty("user.home") + "/.stormpath/apiKey.properties"; 
String applicationUrl = "https://api.stormpath.com/v1/applications/2TqboZ1qo73eDM4gTo2H94"; 
Client client = Clients.builder().setApiKey(ApiKeys.builder().setFileLocation(path).build()).build(); 
Application application = client.getResource(applicationUrl, Application.class); 

public String getAccessToken(ApiKey apiKey) { 
    HttpRequest request = createOauthAuthenticationRequest(apiKey); 
    AccessTokenResult accessTokenResult = (AccessTokenResult) application.authenticateApiRequest(request); 
    System.out.println(accessTokenResult.getScope()); 
    return accessTokenResult.getTokenResponse().getAccessToken(); 
} 

public boolean startEngines(String accessToken) { 
    HttpRequest request = createRequestForOauth2AuthenticatedOperation(accessToken); 
    try { 
     OauthAuthenticationResult result = application.authenticateOauthRequest(request).execute(); 
     System.out.println(result.getAccount().getEmail() + " is about to start the engines!"); 

     doStartEngines(); //Here you will actually call your internal doStartEngines() operation 
     return true; 

    } catch (AccessTokenOauthException e) { 

     //This accessToken is not allowed to start the engines 
     System.out.print("AccessToken: " + accessToken + " just tried to start the engines. He is not allowed to do so."); 
     return false; 

    } 
} 

private HttpRequest createOauthAuthenticationRequest(ApiKey apiKey) { 
    try { 
     String credentials = apiKey.getId() + ":" + apiKey.getSecret(); 

     Map<String, String[]> headers = new LinkedHashMap<String, String[]>(); 
     headers.put("Accept", new String[]{"application/json"}); 
     headers.put("Content-Type", new String[]{"application/x-www-form-urlencoded"}); 
     headers.put("Authorization", new String[]{"Basic " + Base64.encodeBase64String(credentials.getBytes("UTF-8"))}); 

     Map<String, String[]> parameters = new LinkedHashMap<String, String[]>(); 
     parameters.put("grant_type", new String[]{"client_credentials"}); 

     HttpRequest request = HttpRequests.method(HttpMethod.POST) 
       .headers(headers) 
       .parameters(parameters) 
       .build(); 
     return request; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

private HttpRequest createRequestForOauth2AuthenticatedOperation(String token) { 
    try { 
     Map<String, String[]> headers = new LinkedHashMap<String, String[]>(); 
     headers.put("Accept", new String[]{"application/json"}); 
     headers.put("Authorization", new String[]{"Bearer " + token}); 
     HttpRequest request = HttpRequests.method(HttpMethod.GET) 
       .headers(headers) 
       .build(); 
     return request; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

private void doStartEngines() { 
    System.out.println("Server-side message: Engines started!!!"); 
} 

Для простоты я сделал все это код, выполняемый в той же машине (нет сетевая связь между клиентским и серверным кодом). Вам действительно нужно будет выставить startEngines() и String getAccessToken(ApiKey) через Rest API с помощью Spring и предоставить своим конечным пользователям доступ к ним через сеть.

Дайте ему попробовать, это должно быть довольно простое и быстрое решение. :)

Полный disclosure- Я работаю в Stormpath

Смежные вопросы