HTTP基本认证(Basic Authentication)的JAVA示例

参与:

https://blog.csdn.net/thc1987/article/details/54572272 HTTP访问控制(CORS),解决跨域问题

https://blog.csdn.net/VLilyV/article/details/80927833  jquery的ajax is not allowed Access-Control-Allow-Headers in preflight response 自定义headers

调试工具:https://www.cnblogs.com/holiday-testing/p/firebug-fiddler.html  web调试工具总结(firebug/fidder/httpwatch/wireshark)

HTTP基本认证(Basic Authentication)的JAVA示例

关键词: HTTP Basic Auth cors ajax

 

大家在登录网站的时候,大部分时候是通过一个表单提交登录信息。
但是有时候浏览器会弹出一个登录验证的对话框,如下图,这就是使用HTTP基本认证。

下面来看看一看这个认证的工作过程:
第一步:  客户端发送http request 给服务器,服务器验证该用户是否已经登录验证过了,如果没有的话,
服务器会返回一个401 Unauthozied给客户端,并且在Response 的 header "WWW-Authenticate" 中添加信息。
如下图。

第二步:浏览器在接受到401 Unauthozied后,会弹出登录验证的对话框。用户输入用户名和密码后,
浏览器用BASE64编码后,放在Authorization header中发送给服务器。如下图:

 

第三步: 服务器将Authorization header中的用户名密码取出,进行验证, 如果验证通过,将根据请求,发送资源给客户端。

下面来看一个JAVA的示例代码:
 

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sun.misc.BASE64Decoder;
 
public class HTTPAuthServlet extends HttpServlet {
	
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String sessionAuth = (String) request.getSession().getAttribute("auth");
 
		if (sessionAuth != null) {
			System.out.println("this is next step");
			nextStep(request, response);
 
		} else {
 
			if(!checkHeaderAuth(request, response)){
				response.setStatus(401);
				response.setHeader("Cache-Control", "no-store");
				response.setDateHeader("Expires", 0);
				response.setHeader("WWW-authenticate", "Basic Realm=\"test\"");
			}			
 
		}
 
	}
 
	private boolean checkHeaderAuth(HttpServletRequest request, HttpServletResponse response) throws IOException {
 
		String auth = request.getHeader("Authorization");
		System.out.println("auth encoded in base64 is " + getFromBASE64(auth));
		
		if ((auth != null) && (auth.length() > 6)) {
			auth = auth.substring(6, auth.length());
 
			String decodedAuth = getFromBASE64(auth);
			System.out.println("auth decoded from base64 is " + decodedAuth);
 
			request.getSession().setAttribute("auth", decodedAuth);
			return true;
		}else{
			return false;
		}
 
	}
 
	private String getFromBASE64(String s) {
		if (s == null)
			return null;
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			byte[] b = decoder.decodeBuffer(s);
			return new String(b);
		} catch (Exception e) {
			return null;
		}
	}
 
	public void nextStep(HttpServletRequest request, HttpServletResponse response) throws IOException {
		PrintWriter pw = response.getWriter();
		pw.println("<html> next step, authentication is : " + request.getSession().getAttribute("auth") + "<br>");
		pw.println("<br></html>");
	}
 
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
		doGet(request, response);
	}
 
}
————————————————
版权声明:本文为CSDN博主「IT农夫」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kkdelta/article/details/28419625

当request第一次到达服务器时,服务器没有认证的信息,服务器会返回一个401 Unauthozied给客户端。
认证之后将认证信息放在session,以后在session有效期内就不用再认证了。

 

 

 

——————————————————————————————————————————————————————————

转:

jquery中ajax跨域设置http header

今天写api遇到了跨域问题,填坑填了好久...还好有前辈的经验可以借鉴!

 

本文从以下几种情况讨论ajax请求:

没有跨域,设置http header头部(例如authorization);

跨域,没有设置http header头部;

跨域,设置http header头部;

题外,php发送http请求,并设置http header头部;

Jsonp个人理解,参考

一.ajax请求,没有跨域,设置http header头部

$.ajax({

    type: "post",

    url:"http://abc.cc/qrcode3/index.php/home/index/testpost",

    dataType: "json"

    data: {"key":"value"},

    // headers : {'Authorization':'Basic bmVvd2F5Oe4lb3dheQ=='},

    beforeSend: function(xhr) {

        xhr.setRequestHeader("Authorization", "Basic bmVvd2F5Oe4lb3dheQ==");

    },

    success: function(data){ alert(data); },

    error: function(data){ alert("error"); } ,

});

设置header头部有两种方法:

1.headers : {‘Authorization’:’Basic bmVvd2F5Oe4lb3dheQ==’}

多个头部用逗号‘,’分隔开

2.定义beforeSend方法

beforeSend: function(xhr) {

xhr.setRequestHeader(“Authorization”, “Basic bmVvd2F5Oe4lb3dheQ==”);

}

二.ajax跨域请求,没有设置http header,

$.ajax({

    type: "post",

    url:"http://abc.cc/qrcode3/index.php/home/index/testpost",

    dataType: "jsonp"

    data: {"key":"value"},

    // headers : {'Authorization':'Basic bmVvd2F5Oe4lb3dheQ=='},

    success: function(data){ alert(data); },

    error: function(data){ alert("error"); } ,

});

服务器端代码:

public function testpost() {

    $data = $_GET['key']?$_GET['key']:"123456";

    $callback = $_GET['callback'];

    if(!preg_match("/^[0-9a-zA-Z_.]+$/",$callback)){

exit('参数错误!');

    }

    echo $callback.'('.json_encode($data).')';

    exit;

}

跨域ajax访问,使用jsonp,返回数据格式如:abc({'key':'value','key2':'value2'}),形如一个函数调用,参数为一个json数据格式

三.ajax跨域请求,设置header头部的解决办法

跨域无法直接设置header,如果跨域了还要设置http头,可以使用以下方法。

jquery实现代码如下:

$(".get_data").click(function() {

    var key = $("#user").val() + ":" + $("#pass").val();

    //base64编码

    var authKey = base64encode(key);

    $.ajax({

        type: 'GET',

        dataType: 'json',

        url: "http://abc.cc/qrcode3/home/index/testajax",

        headers: {'Authorization': 'Basic '+authKey,"lpy":"lpy"},

        success: function(data) {

            alert(data.msg+"--"+data.user);

        },

        error:function(data){

            alert("error");

        }

    });

});

 

php实现代码如下:

public function testajax() {

    // 指定允许其他域名访问  

    header('Access-Control-Allow-Origin:http://abc.cn');  

    // 响应类型  

    header('Access-Control-Allow-Methods:POST,GET');  

    // 响应头设置,允许设置Authorization和lpy这两个http头

header('Access-Control-Allow-Headers:Authorization,lpy');

 

    //获取所有的http请求头

    $header = apache_request_headers();

$data['lpy'] = $header['lpy'];

//获取authorization中的用户名和密码,并判断

    $data['user'] = $_SERVER['PHP_AUTH_USER'];

    $data['pass'] = $_SERVER['PHP_AUTH_PW'];

    if($data['user'] == "neoway" && $data['pass'] == "neoway"){

        $data['msg'] = "ok";

    }else{

        $data['msg'] = "errorjsonp";

    }

echo json_encode($data);

}

总结:

ajax跨域是不能设置http header的,为了能够设置header,需要在服务器php代码中添加header(‘Access-Control-Allow-Origin:http://abc.cn’); 允许http://abc.cn访问服务器abc.cc,再通过设置header(‘Access-Control-Allow-Headers:Authorization,lpy’);把需要设置的http header属性添加进去,在jquery代码中通过header来设置响应的属性值,在http的请求头中就可以看到 Authorization和lpy的请求头,服务器php端通过$header = apache_request_headers()获取http header的数组,继而可以获取到lpy的请求头的值。

四.php发送http请求,不存在跨域,有设置http header, 示例如下:

$http_url = "http://abc.cc/qrcode3/index.php/home/index/testpost";

$opts = array(

    'http' => array(

    'method' => 'POST',

    'header' => "Content-type:application/json\r\nAuthorization:Basic bmVvd2F5Oe4lb3dheQ==",

    'content' => $encodeString  //body内容,传递的参数

    )

);

$context = stream_context_create($opts);

echo  $res = file_get_contents($http_url, false, $context);

设置多个header信息时,中间的换行使用\r\n

$encodeString为body内容,传递的参数

五.jsonp的理解

JSONP请求不是一个真正的Ajax调用。它将一个脚本标签到您的网页和浏览器然后请求脚本SRC文件。生成的脚本,返回执行和沟通后的结果通过JavaScript执行(调用回调函数),这是为什么要设置jsonpcallback的原因。因为请求是通过一个脚本标签插入而不是直接的Ajax调用生成的,是没有能力去设置请求头。为了防止被攻击,对jsonpcallback的值要进行匹配,屏蔽常见特殊字符” <> ()’”;. {}“,以下这些字符,经常会用到xss里面的,防止xss攻击。

感兴趣的可以看看这几篇文章,分析京东商城jsonp漏洞(文章比较早):

http://blog.chacuo.net/295.html

http://blog.chacuo.net/304.html

http://blog.chacuo.net/323.html

参考:

http://www.cnblogs.com/aheizi/p/5031516.html

http://kb.cnblogs.com/page/139725/

http://blog.csdn.net/enter89/article/details/51205752

文章内容转自:http://blog.163.com/pei_jia123/blog/static/230990078201711003348615/



作者:雨伞不挡雨
链接:https://www.jianshu.com/p/34af1f99f9d9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java发送带Basic Auth认证HTTP POST请求的示例代码: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Base64; public class HttpPostWithBasicAuth { public static void main(String[] args) throws IOException { String url = "http://example.com/api/resource"; String username = "myusername"; String password = "mypassword"; String postData = "param1=value1&param2=value2"; URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); // set request method con.setRequestMethod("POST"); // set basic authentication header String auth = username + ":" + password; byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8)); String authHeaderValue = "Basic " + new String(encodedAuth); con.setRequestProperty("Authorization", authHeaderValue); // set post data con.setDoOutput(true); con.getOutputStream().write(postData.getBytes("UTF-8")); // get response int responseCode = con.getResponseCode(); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); // print response System.out.println("Response code: " + responseCode); System.out.println("Response body: " + response.toString()); } } ``` 在上面的代码中,我们使用 `HttpURLConnection` 类来建立HTTP连接,并设置了请求头中的基本认证信息。我们还设置了POST数据,并获取了响应,最后打印了响应码和响应体。请注意,此示例仅用于演示目的,实际使用中需要根据实际情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值