Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将用户名和密码从非web客户端传递到RestController服务,并在服务中检索它_Java_Rest_Spring Security_Apache Httpclient 4.x - Fatal编程技术网

Java 将用户名和密码从非web客户端传递到RestController服务,并在服务中检索它

Java 将用户名和密码从非web客户端传递到RestController服务,并在服务中检索它,java,rest,spring-security,apache-httpclient-4.x,Java,Rest,Spring Security,Apache Httpclient 4.x,部署在Internet上的遗留java应用程序正在尝试与AuthenticationService通信,AuthenticationService是基于Spring Security的应用程序,位于Intranet上。AuthenticationService在发送用户名和密码时对任何用户进行身份验证。客户端代码为: public static void ApacheHttpClient(String userID, String userPWD){ Creden

部署在Internet上的遗留java应用程序正在尝试与AuthenticationService通信,AuthenticationService是基于Spring Security的应用程序,位于Intranet上。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();
        }
用于接受用户名和密码并进行身份验证的AuthenticationService代码。这里,字符串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基本或摘要身份验证。我想了解从非基于web的应用程序向服务发送和检索用户名/密码的方法。比如,登录应该是一个POST方法,用户名和密码应该作为queryparam或pathparam等传递。好的,这里有几件事

  • 如果AuthenticationService设置正确,ApacheHttpClient将正常工作。 因此,让我们假设您相信您的AuthenticationService使用Spring Security工作。 请:
  • curl-ihttp://localhost:8080/abc/login

    你看到这样的回应了吗

    HTTP/1.1 401未经授权
    WWW Authenticate:Basic realm=“Spring安全应用程序”

    如果您没有看到
    WWW-Authenticate
    标题。那么您的AuthorizationService没有设置为处理基本身份验证。您没有配置Spring Security为您执行基本身份验证

    您知道,为基本身份验证设置的应用程序将使用401响应和头自动质询客户端(如浏览器或您的HttpClient)

  • 假设您不希望Spring安全性保护您的端点 在这种情况下,您可以将HttpClient配置为在任何请求时始终发送
    授权
    头(而不是像1中所述等待质询)

    代码如下所示:

    public静态字符串ApacheHttpClient(字符串userID,
    字符串userPWD,
    字符串url,
    布尔抢占)引发异常{
    CredentialsProvider=new BasicCredentialsProvider();
    UsernamePasswordCredentials凭据=新的UsernamePasswordCredentials(userID,userPWD);
    provider.setCredentials(AuthScope.ANY,credentials);
    HttpClientContext=HttpClientContext.create();
    HttpClientBuilder=HttpClientBuilder.create();
    如果(抢占){
    AuthCache AuthCache=new BasicAuthCache();
    authCache.put(HttpHost.create(url),newBasicScheme());
    context.setCredentialsProvider(提供者);
    setAuthCache(authCache);
    }否则{
    builder.setDefaultCredentialsProvider(提供者);
    }
    HttpClient=builder.build();
    试一试{
    HttpResponse response=client.execute(新的HttpGet(url),上下文);
    int statusCode=response.getStatusLine().getStatusCode();
    System.out.println(“响应状态代码:“+statusCode”);
    返回EntityUtils.toString(response.getEntity());
    }最后{
    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
    
    首先访问非安全页面:

    然后访问安全页面:

    输入
    user/password
    作为您的凭据,并点击刷新几次


    我还为您添加了代码,how to

    Hi@Filip AuthenticationService运行得非常好,因为如果我硬编码用户名和密码,该服务将对我进行身份验证并返回ldap详细信息。此外,如果我通过硬编码用户名和密码调用服务,我会在客户端得到200 OK响应。我想要一些技巧来传递来自客户的凭据,以及如何以更好的方式在服务中处理它们。hi@Pan-看看我为您准备的示例项目。它应该解释一切,但你必须仔细看看。如果你硬编码,你会得到一个200OK,因为你还没有真正设置基本的身份验证来支持你的客户所期望的401响应挑战。你也没有说过我试过你发布的
    ApacheHttpClient
    代码,我设置了
    preempt=true
    ,它又工作了。在编写利用Spring安全性的应用程序时,您不必自己进行任何基本的身份验证。一切都为你准备好了。例如,如果你改变了:看看我的。我不必解析基本的身份验证头。Spring Security为我做了这件事。httpBasic()已配置,使用curl-I不会得到任何错误401响应。但是,java.lang.IllegalArgumentException:无效的HTTP主机:在authCache.put(HttpHost.create(url),new BasicScheme()行抛出错误;在org.apache.http.HttpHost.create(HttpHost.java:122)上,当我设置url=”“hi-Pan时,首先将http://添加到您的url,如果这仍然不起作用,那么可能是不同版本的HttpClient库?请检查(可能自己运行)