通过HTTP协议认证方式弹出用户名和密码对话框

 

认证模式由浏览器与Web服务器之间约定。它有很多不同的模式,有些可能是按照HTTP协议规范,有些是在HTTP协议之上制定出来的,有些则建立在HTTPS之上。不同模式有不同的特点,下面讨论常见的一些认证模式。
1.Basic模式
HTTP协议规范中有两种认证方式,一种是Basic认证方式,另外一种是Digest认证方式。这两种方式都属于无状态认证方式,所谓无状态即服务器端都不会在会话中记录相关信息,客户端每次访问都需要将用户名和密码放置到报文中一同发送给服务端,但这并不表示你在浏览器中每次访问时都要自己输入用户名和密码,可能是你第一次输入账号后浏览器就把它保存在内存中用于后面的交互。先看HTTP协议的Basic认证模式。
既然是HTTP协议规范,那其实就是约束浏览器厂商与Web容器厂商实现各自软件时的行为约束。例如,一个典型的认证交互过程是:浏览器向Web容器发送HTTP请求报文,Web容器接收到HTTP请求报文后解析需要访问的资源。如果该资源刚好是受保护的资源,Web容器则向浏览器发送认证HTTP响应报文,浏览器接收到报文后弹出窗口让用户输入账号及密码。接着,再次发送包含了账号信息的HTTP请求报文,Web容器对账号信息进行鉴权,如果通过验证,则返回对应资源,否则重新认证。
Basic Access Authentication scheme是在HTTP 1.0中提出的认证方法。它是一种基于Challenge/Response的认证模式,针对特定的Realm需要提供用户名和密码认证后才可访问,其中密码使用明文传输。Basic模式的认证过程如下。
① 浏览器发送HTTP报文请求一个受保护的资源。
② 服务器端的Web容器将HTTP响应报文的响应码设为401,响应头部加入WWW- Authenticate: Basic realm="input username and password"中。
③ 浏览器弹出对话框让用户输入用户名和密码,并用Base64进行编码,实际上是用户名+冒号+密码进行Base64编码,即Base64(username:password),这次浏览器就会在HTTP报文头部加入"Authorization: Basic bXl0b21jYXQ="。
④ 服务器端Web容器获取HTTP报文头部的相关认证信息,确认此用户名与密码是否正确,是否有相应资源的权限,如果认证成功,则返回相关资源,否则再执行步骤②,重新进行认证。
⑤ 以后每次访问都要带上认证头部。
服务器端返回的认证报文中包含了realm="myTomcat"。realm的值用于定义保护的区域,在服务器端可以通过realm将不同的资源分成不同的域,域的名称即为realm的值,每个域可能会有自己的权限鉴别方案。
Basic认证模式有两个明显的缺点:①无状态导致每次通信都要带上认证信息,即使是已经认证过的资源;②传输安全性不足,认证信息用Base64编码,基本上就是明文传输,很容易截取报文并盗用认证信息。

@GetMapping("app/sys/hehe")
    public void a(HttpServletRequest request, HttpServletResponse response) {

        try {
            response.setCharacterEncoding("utf-8");
            PrintWriter out = response.getWriter();
            String authorization = request.getHeader("Authorization");
            if (authorization == null || authorization.equals("")) {
                response.setStatus(401);
                response.setHeader("WWW-Authenticate", "Basic realm=\"input username and password\"");
                response.setContentType("text/html;charset=utf8");
                out.print("401 认证失败");
                return;
            }

            String userAndPass = Base64Decoder.decodeStr(authorization.split(" ")[1]);
            if (userAndPass.split(":").length < 2) {
                response.setStatus(401);
                response.setHeader("WWW-Authenticate", "Basic realm=\"input username and password\"");
                response.setContentType("text/html;charset=utf8");
                out.print("401 认证失败");
                return;
            }

          String  user = userAndPass.split(":")[0];
            String pass = userAndPass.split(":")[1];
            if (user.equals("111") && pass.equals("111")) {
                // 跳转合适的地方
            } else {
                response.setStatus(401);
                response.setHeader("WWW-Authenticate", "Basic realm=\"input username and password\"");
                response.setContentType("text/html;charset=utf8");
                out.print("401 认证失败");
                return;
            }

        } catch (Exception ex) {
            ex.printStackTrace();

        }

    }


2.Digest模式
HTTP协议规范的另一种认证模式是Digest模式,在HTTP 1.1时提出。它主要是为了解决Basic模式安全问题,用于替代原来的Basic认证模式。Digest认证也采用Challenge/Response认证模式,基本的认证流程比较类似,整个过程如下。
① 浏览器发送HTTP报文请求一个受保护的资源。
② 服务器端的Web容器将HTTP响应报文的响应码设为401,响应头部比Basic模式复杂,WWW-Authenticate: Digest realm="myTomcat",qop="auth",nonce="xxxxxxxxxxx",opaque= "xxxxxxxx"。其中,qop的auth表示鉴别方式;nonce是随机字符串;opaque服务器端指定的值,客户端需要原值返回。
③ 浏览器弹出对话框让用户输入用户名和密码,浏览器对用户名、密码、nonce值、HTTP请求方法、被请求资源URI等组合后进行MD5运算,把计算得到的摘要信息发送给服务器端。请求头部类似如下,Authorization: Digest username="xxxxx",realm="myTomcat",qop="auth",nonce= "xxxxx",uri="xxxx",cnonce="xxxxxx",nc=00000001,response="xxxxxxxxx",opaque="xxxxxxxxx"。其中,username是用户名;nonce是客户端生成的随机字符串;nc是运行认证的次数;response就是最终计算得到的摘要。
④ 服务器端Web容器获取HTTP报文头部的相关认证信息,从中获取到username,根据username获取对应的密码,同样对用户名、密码、nonce值、HTTP请求方法、被请求资源URI等组合进行MD5运算,把计算结果和response进行比较,如果匹配,则认证成功并返回相关资源,否则再执行步骤②,重新进行认证。
⑤ 以后每次访问都要带上认证头部。
其实通过散列算法对通信双方身份的认证十分常见。它的好处就是不必把具备密码的信息对外传输,只须将这些密码信息加入一个对方给定的随机值计算散列值,最后将散列值传给对方,对方就可以认证你的身份。Digest思想同样采如此,用了一种nonce随机数字符串,双方约好对哪些信息进行散列运算即可完成双方身份的验证。Digest模式避免了密码在网络上明文传输,提高了安全性,但它仍然存在缺点,例如,认证报文被攻击者拦截到,攻击者可以获取到资源。
3.Form模式
上面介绍的两种模式都属于HTTP协议规范的范畴。由于它的规范使得很多东西无法自定义,例如登录窗口、错误展示页面,所以需要另外一种模式以提供更加灵活的认证,也就是基于Form的认证模式。各种语言体系的Web容器都可以实现各自的Form模式,这里只介绍Java体系的Form认证模式。
Form模式的认证流程如下。
① 浏览器发送HTTP报文请求一个受保护的资源。
② 服务器端的Web容器判断此URI为受保护的资源,于是将请求重定向到自定义的登录页面上,例如login.html页面。可以自定义登录页面的样式,但要遵守的约定是表单的action必须以j_security_check结尾,即<form action=’xxxxxx/j_security_check’ method=’POST’>。用户名和密码输入框元素的name必须为’j_username’ 和’j_password’。
③ 浏览器展示自定义的登录页面让用户输入用户名和密码,然后提交表单。
④ 服务器端Web容器获取表单的用户名和密码,确认此用户名与密码是否正确,是否有相应资源的权限,如果认证成功,则返回相关资源,否则再执行步骤②,重新进行认证。
⑤ 后面在同个会话期间的访问都不用再进行认证,因为认证的结果已经保存在服务器端的会话里面。
Form模式跳出了HTTP规范提供了自定义的更加灵活的认证模式。由于每种语言都可以定义自己的Form模式,因此它没有一个通用的标准,而且它也存在密码明文传输安全问题。
4.Spnego模式
Spnego模式是一种由微软提出的使用GSS-API接口的认证模式。它扩展了Kerberos协议,在了解Spnego协议之前,必须先了解Kerberos协议。Kerberos协议主要解决身份认证及通信密钥协商问题,它大致的工作流程如图17.12所示。
① 客户端根据自己用户名向密钥分发中心KDC的身份认证服务(AS)请求TGS票证。
② AS生成一个TGS票证,查询对应用户的密码,然后通过用户密码将TGS票证加密,响应给客户端。
③ 客户端通过用户密码解密TGS票证,如果密码正确,就能获取到TGS票证,然后用TGS票证向票证授予服务请求服务票证。
④ TGS将服务票证响应给客户端。
⑤ 客户端使用服务票证去访问某服务,该服务会验证服务票据是否合法。
⑥ 验证通过,开始通信。

Spring Security 是一个基于 Spring 的安全框架,可以实现身份认证和授权。 1. 身份认证 Spring Security 提供了多种身份认证方式,如: - 基于表单的身份认证:用户在表单中输入用户名密码,Spring Security 对用户进行认证。 - 基于 HTTP Basic 认证:浏览器发送请求时,会弹出认证对话框,用户在对话框输入用户名密码,Spring Security 对用户进行认证。 - 基于 OAuth2 认证:支持 OAuth2 协议的身份认证方式。 Spring Security 还提供了多种身份认证方式的扩展,如: - 自定义身份认证过滤器:可以自定义身份认证过滤器,实现自己的身份认证逻辑。 - 自定义身份认证提供者:可以自定义身份认证提供者,实现自己的身份认证逻辑。 2. 授权 Spring Security 提供了多种授权方式,如: - 基于角色的授权:可以配置角色和权限之间的映射关系,在访问资源时,根据用户的角色判断用户是否有权限访问资源。 - 基于表达式的授权:可以使用 SpEL 表达式进行授权,可以根据用户的属性、角色等信息进行授权判断。 - 基于注解的授权:可以使用注解对方法或类进行授权,可以根据用户的属性、角色等信息进行授权判断。 Spring Security 还提供了多种授权方式的扩展,如: - 自定义访问控制过滤器:可以自定义访问控制过滤器,实现自己的授权逻辑。 - 自定义访问控制决策器:可以自定义访问控制决策器,实现自己的授权逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值