2015-01-02 2 views
1

Я реализовал очень простой HTTP-сервер, как описано here. Мне удалось получить аутентификацию, используя заголовок Authentication, но я не могу понять, как взять учетные данные из формы и использовать их для аутентификации с сервером. Как это обычно делается?Проверка подлинности Java HTTPServer - сторона клиента

Edit: (по peeskillet, чтобы показать код из ссылки)

import java.io.IOException; 
import java.io.OutputStream; 
import java.net.InetSocketAddress; 

import com.sun.net.httpserver.BasicAuthenticator; 
import com.sun.net.httpserver.HttpContext; 
import com.sun.net.httpserver.HttpExchange; 
import com.sun.net.httpserver.HttpHandler; 
import com.sun.net.httpserver.HttpServer; 

public class SimpleHttpServer3 { 

    public static void main(String[] args) throws Exception { 
    HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0); 
    server.createContext("/info", new InfoHandler()); 
    HttpContext hc1 = server.createContext("/get", new GetHandler()); 
    hc1.setAuthenticator(new BasicAuthenticator("get") { 
     @Override 
     public boolean checkCredentials(String user, String pwd) { 
      return user.equals("admin") && pwd.equals("password"); 
     } 
    }); 
    server.setExecutor(null); // creates a default executor 
    server.start(); 
    System.out.println("The server is running"); 
    } 

    // http://localhost:8000/info 
    static class InfoHandler implements HttpHandler { 
    public void handle(HttpExchange httpExchange) throws IOException { 
     String response = "Use /get to authenticate (user:admin pwd:password)"; 
     SimpleHttpServer3.writeResponse(httpExchange, response.toString()); 
    } 
    } 

    static class GetHandler implements HttpHandler { 
    public void handle(HttpExchange httpExchange) throws IOException { 
     StringBuilder response = new StringBuilder(); 
     response.append("<html><body>"); 
     response.append("hello " + httpExchange.getPrincipal().getUsername()); 
     response.append("</body></html>"); 
     SimpleHttpServer3.writeResponse(httpExchange, response.toString()); 
    } 
    } 

    public static void writeResponse(HttpExchange httpExchange, String response) throws IOException { 
    httpExchange.sendResponseHeaders(200, response.length()); 
    OutputStream os = httpExchange.getResponseBody(); 
    os.write(response.getBytes()); 
    os.close(); 
    } 

} 

ответ

1

Как правило, большинство людей используют структуру аутентификации, как Shiro или Spring Security.

Эти рамки регистрируют фильтр сервлетов на шаблоне, например /*, чтобы обеспечить аутентификацию для всех запросов. Они хранят данные аутентификации в сеансе Servlet, чтобы пользователи регистрировались между запросами, которые обычно выполняются HTTP-сервером неявно через Cookies. Они также регистрируют специальный контекст для приема запросов на аутентификацию на основе форм, таких как запросы POST, до /login.

Эти конечные точки на основе формы будут читать, как правило, application/x-www-form-urlencoded, запросить и вывести предоставленное имя пользователя и пароль, ввести пароль так же, как сервер хранит пароль и сравнить их, чтобы проверить принципы аутентификации.

+0

Я старался избегать Весны, так как он казался чуть более вершиной для моего очень простого проекта, но в конце мне кажется, что это мой лучший выбор –

+0

@SamanthaCatania, я согласен, если вы пытаетесь сохранить его простым с Shiro, это отличная инфраструктура и не требует каких-либо дополнительных внешних зависимостей. – Alex

+0

У Spring, похоже, больше поддержка браузеров на стороне клиента или я что-то пропустил? –

0

Basic Authentication протокола заявляет запрос клиент должен иметь заголовок в виде

Authorization: Basic Base64Encoded(username:password) 

, где Base64Encoded(username:password) является актуальной кодировке Base64 строки из username:password. Например, если мое имя пользователя и пароль peeskillet:pass, заголовок должен быть разослан в

Authorization: Basic cGVlc2tpbGxldDpwYXNz 

В the example from your link, он использует обычную проверку подлинности. URL к защищаемому ресурсу

http://localhost:8000/get 

Вы можете перейти в свой браузер на URL, и вы увидите диалоговое окно (в Firefox), как показано на this answer. Введите admin (имя пользователя) и password (пароль). Вы получите сообщение об ошибке hello admin.

Вам не нужно выполнять аутентификацию самостоятельно (или, по крайней мере, разбор/декодирование), как внутренне (я не проверял исходный код, но, похоже, это так) BasicAuthenticator декодирует и анализирует Authorization заголовок и передает имя пользователя и пароль методу checkCredentials, который вы реализуете. Поскольку он просто разрешает только admin/password, это единственная комбинация, которая будет аутентифицироваться.

Просто для полноты картины, декодирование/разбор (в псевдокоде) может выглядеть примерно так

String authHeader = request.getHeader("Authorization"); 
String[] split = authHeader.split("\\s"); 
String credentials = split[1]; 
String decoded = Base64.decode(credentials); 
String[] userPass = decoded.split(":"); 

String username = userPass[0]; 
String password = userPass[1]; 

boolean authenticated = checkCredentials(username, password); 

Если вы хотите, чтобы попытаться сделать запрос с кодом, то вам нужно будет установить заголовок Authorization в запросе. Значение будет представлять собой кодировку Base64 с кодом admin:password, которая равна YWRtaW46cGFzc3dvcmQ=.Таким образом, заголовок должен быть разослан в

Authorization: Basic YWRtaW46cGFzc3dvcmQ= 

Для других комбинаций, вы можете просто go here ввести в комбинации, или Java 8 имеет java.util.Base64 класс, который можно использовать для кодирования учетных

String cred = "admin:password"; 
String encoded = Base64.getEncoder().encodeToString(cred.getBytes()); 
System.out.println(encoded); 
// YWRtaW46cGFzc3dvcmQ= 

EDIT: Обозначение как (информационное) сообщество wiki, так как неясно, что пытается сделать OP.

+0

В исходном вопросе говорится, что он работает с базовой аутентификацией, и искал информацию о том, как работают бэк-логины, что подразумевает использование сеанса и т. Д. И это относится к категории «не изобретать колесо» в качестве таких рамок, как Сиро или Spring Security хорошо установлены при сохранении состояния аутентификации – Alex

+0

@Alex true, я, возможно, неправильно понял или неправильно понял, но OP также не указал клиента. Для всех, кого мы знаем, это приложение Swing, с которым OP работает. Там слишком много возможностей. Но, не зная клиента, которого OP намеревается использовать, я не думаю, что любой ответ - это просто какие-то варианты, брошенные на стену, надеясь, что это застрянет :-) Но вы, кажется, правильно относитесь к моему возможному непониманию вопроса. Мы можем дождаться разъяснений от ОП –

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