2017-02-06 5 views
2

В настоящее время я использую этот метод для отправки имени пользователя и пароля на мой бэкэнд и проверки правильности в базе данных. код здесь:Как мне отправить свое имя пользователя и пароль на сервер в Java?

@GET 
@Path("/login/{username}/{passWord}") 
public Boolean Login(@PathParam("username") String username, @PathParam("passWord") String password) { 
    LoginService login = new LoginService(); 
    boolean response = login.LoginCheck(username, password); 
    return response; 
} 

И в LoginService Я использую этот метод для проверки ::

public class LoginService { 
    private int count;  
    public LoginService() {}     
    public boolean LoginCheck(String uname, String password) { 
     SessionFactory factory = new Configuration().configure().buildSessionFactory(); 
     Session session = SessionUtil.getSession(); 
     String hql = "select reg.name,reg.password from Employee as reg where reg.name='" + uname + "' and reg.password='" + password + "'"; 
     Query query = session.createQuery(hql); 
     for (Iterator it = query.iterate(); it.hasNext();) {    
      it.next(); 
      count++; 
     } 
     System.out.println("Total rows: " + count); 
     if (count == 1) { 
      return true; 
     } else { 
      return false; 
     } 
    }  
} 

Я хочу знать, есть ли другой безопасный способ отправить имя пользователя и пароль? Как здесь, имя пользователя и пароль отображаются в URL-адресе.

Спасибо заранее.

+3

Никогда не храните пароли в текстовом формате !!! Хеш (с солью) пароль на клиенте. Отправьте его на сервер и проверьте, что хэш против сохраненного хэша –

+1

Отправка пароля в текстовом формате не является проблемой, если использование * безопасного соединения * (например, HTTPS) - отправка «сохраненного хэша» с клиента обычно менее безопасна, поскольку то хэш * становится * незашифрованным паролем. В бэкэнд следуйте стандартным правилам управления и хранения паролей (с действительными алгоритмами хэша, солью, разделением принципов безопасности и т. Д.) - эта тема была избита до смерти, и поэтому я голосую как слишком широко. – user2864740

ответ

1

Вы должны рассмотреть возможность использования Basic Auth (RFC 2617). Сервлет фильтр его реализации может выглядеть следующим образом:

package transfer.util; 

import static org.apache.commons.lang3.StringUtils.*; 

import java.io.IOException; 
import java.security.Principal; 

import javax.servlet.FilterChain; 
import javax.servlet.ServletException; 
import javax.servlet.annotation.WebFilter; 
import javax.servlet.http.Cookie; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletRequestWrapper; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpSession; 
import javax.ws.rs.core.HttpHeaders; 

import org.omnifaces.filter.HttpFilter; 

import transfer.business.users.entity.Roles; 

@WebFilter("/api/*") 
public class BasicAuthFilter extends HttpFilter { 

    @Override 
    public void doFilter(final HttpServletRequest request, final HttpServletResponse response, final HttpSession session, final FilterChain chain) throws ServletException, IOException { 

     // insert cookie erasure here if needed 

     dontCache(response); 

     final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION); 

     if (isNotBlank(authHeader)) { 
      if (isValid(authHeader)) { 
       chain.doFilter(wrapRequest(request, new SimplePrincipal(webHookUser, Roles.ISSUETRACKER)), response); 
      } else { 
       sendAuthError(response); 
      } 
     } else { 
      sendAuthError(response); 
     } 
    } 

    private void dontCache(final HttpServletResponse response) { 
     response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); 
     response.setHeader("Pragma", "no-cache"); 
     response.setDateHeader("Expires", 0); 
    } 

    private boolean isValid(final String authHeader) { 
     // check credentials and return true or false 
    } 

    private HttpServletRequest wrapRequest(final HttpServletRequest request, final SimplePrincipal principal) { 
     final HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request) { 
      @Override 
      public Principal getUserPrincipal() { 
       return principal; 
      } 

      @Override 
      public String getRemoteUser() { 
       return principal.getName(); 
      } 

      @Override 
      public boolean isUserInRole(final String role) { 
       return principal.getRoles().contains(role); 
      } 
     }; 
     return wrapper; 
    } 

    private void sendAuthError(final HttpServletResponse response) throws IOException { 

     response.setHeader("WWW-Authenticate", "Basic realm=\"default\""); 
     response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
    } 
} 

Этот пример использует OmniFaces и Apache Commons Lang. Он не показывает конкретный запрос проверки для учетных данных пользователя. См. Giovanni Lovatos answer по адресу Параметрированные SQL-запросы. Как он также упоминает, это безопасно только через HTTPS, который добавляет транспортное шифрование и аутентификацию сервера и, возможно, аутентификацию клиента через сертификаты. Конфигурация HTTPS/TLS отличается от реализаций сервера Java-приложений.

0

Более безопасный способ отправить имя пользователя и пароль данные на внутренний интерфейс может быть POST запросом, который будет препятствовать имея оба поля в запросе URL:

@POST 
@Path("/login") 
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) 
public boolean login(@FormParam("username") String username, 
        @FormParam("password") String password) { 
    LoginService login = new LoginService(); 
    boolean response = login.LoginCheck(username, password); 
    return response; 
} 

Затем, если вы используете HTML форма для входа, вы будете иметь что-то вроде этого:

<form method="post" action="/login"> 
    <input type="text" name="username"> 
    <input type="password" name="password"> 
</form> 

Обратите внимание, что POST запрос будет по-прежнему иметь пароль в открытом виде в своем теле, так что обязательно для безопасности, чтобы служба работает в TLS (т.е. над HTTPS).

Наименее, но не последний, вы должны абсолютно избегать создания SQL-запросов с конкатенацией строк, особенно когда речь идет о паролях, поскольку это может привести к SQL Injection [1]. Вы должны использовать подготовленные заявления и параметры, поставляемые довольно легко с Hibernate:

String hql = "select reg.name, reg.password from Employee as reg where reg.name = ? and reg.password = ?"; 
Query query = session.createQuery(hql); 
query.setParameter(1, uname); 
query.setParameter(2, password); 
  1. https://en.wikipedia.org/wiki/SQL_injection
+1

Использование POST является более чистым, но не намного безопаснее. Это только мешает кому-то в вашей спине увидеть параметры, но это не составит труда найти параметр формы в запросе. Но определенно лучше использовать 'PreparedStatement'! – AxelH

+0

@AxelH Я добавил примечание о том, что сервис проходит через TLS. –

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