Передача имени пользователя и пароля от не-веб-клиентов в службу RestController и получение его в службе - PullRequest
0 голосов
/ 08 января 2019

Устаревшее Java-приложение, развернутое в Интернете, пытается установить связь с сервисом AuthenticationService, который является приложением на основе Spring Security, и в интрасети. AuthenticationService аутентифицирует любого пользователя при отправке имени пользователя и пароля. Код клиента:

    public static void ApacheHttpClient(String userID, String userPWD){
            CredentialsProvider provider = new BasicCredentialsProvider();
            UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(userID, userPWD);
            provider.setCredentials(AuthScope.ANY, credentials);

            HttpClient client = HttpClientBuilder.create()
              .setDefaultCredentialsProvider(provider)
              .build();
            String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://localhost:8080/abc/login";
            try {

                HttpResponse response = client.execute(
                  new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION));
                int statusCode = response.getStatusLine()
                  .getStatusCode();
              System.out.println("Response Status Code : "+statusCode);
              HttpEntity entity = response.getEntity();
} catch (Exception e) {
          e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }

Код службы аутентификации для принятия имени пользователя и пароля и аутентификации. Здесь String auth = request.getHeader ("Авторизация"); всегда приходит ноль

@RestController
@RequestMapping("/abc")
public class Authenticate {

     @Autowired
        private LoginService loginService;

    @RequestMapping("/login")
    public void login(HttpServletRequest request, HttpServletResponse response) {
        try {
            String auth = request.getHeader("Authorization");
            if(auth != null && auth.length() > 6){
                String userpassEncoded = auth.substring(6);  
                // Decode it, using any base 64 decoder  
                sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder();  
                String userpassDecoded= new String(dec.decodeBuffer(userpassEncoded));
                System.out.println(" userpassDecoded = "+userpassDecoded);
             }
           } catch (Exception e) {
            e.printStackTrace();
           }

           }

Обычно рекомендуется использовать HTTP Basic или Digest Authentication. Я хочу понять подход к отправке и извлечению имени пользователя / пароля из не веб-приложения в сервис. Например, логин должен быть методом POST, а имя пользователя и пароль должны быть переданы как queryparam или pathparam и т.д.

1 Ответ

0 голосов
/ 08 января 2019

Хорошо, здесь происходит несколько вещей.

  1. Ваш ApacheHttpClient будет работать, если ваш AuthenticationService был правильно настроен. Итак, давайте предположим, что вы считаете, что ваш AuthenticationService работает с использованием Spring Security. Пожалуйста, сделайте:

curl -i http://localhost:8080/abc/login

Вы видите ответ, который выглядит следующим образом?

HTTP/1.1 401 Unauthorized WWW-Authenticate: Basic realm="Spring Security Application"

Если вы не видите заголовок WWW-Authenticate. Тогда ваш AuthorizationService не настроен для обработки базовой аутентификации. Вы не настроили Spring Security для обычной аутентификации.

Видите ли, приложение, настроенное для обычной проверки подлинности, должно автоматически запрашивать у клиента (например, браузера или вашего HttpClient) ответ 401 и заголовок.

  1. Предположим, вы не хотите, чтобы Spring Security защищал вашу конечную точку.

В этом сценарии вы можете настроить свой HttpClient так, чтобы он всегда отправлял заголовок Authorization при каждом запросе (вместо ожидания вызова, как описано в 1.)

Код будет выглядеть примерно так:

public static String ApacheHttpClient(String userID,
                                    String userPWD,
                                    String url,
                                    boolean preempt) throws Exception {
    CredentialsProvider provider = new BasicCredentialsProvider();
    UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(userID, userPWD);
    provider.setCredentials(AuthScope.ANY, credentials);
    HttpClientContext context = HttpClientContext.create();

    HttpClientBuilder builder = HttpClientBuilder.create();
    if (preempt) {
        AuthCache authCache = new BasicAuthCache();
        authCache.put(HttpHost.create(url), new BasicScheme());
        context.setCredentialsProvider(provider);
        context.setAuthCache(authCache);
    } else {
        builder.setDefaultCredentialsProvider(provider);
    }
    HttpClient client = builder.build();
    try {
        HttpResponse response = client.execute(new HttpGet(url), context);
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("Response Status Code : " + statusCode);
        return EntityUtils.toString(response.getEntity());
    } finally {
        client.getConnectionManager().shutdown();
    }
}

Я создал несколько сэмплов, чтобы вы могли поиграться с

git clone https://github.com/fhanik/spring-security-community.git
cd spring-security-community
./gradlew :spring-security-community-samples-basic-authentication-client:bootRun

Первое посещение незащищенной страницы: http://localhost:8080/non-secure

Затем перейдите на защищенную страницу: http://localhost:8080/secure

Введите user/password в качестве учетных данных и несколько раз нажмите обновить

Я также добавил код для вашего клиента и как проверить его

...