Web 应用程序中的 NTLM 身份验证 (java) [英] NTLM Authentication in a Web Application (java)

查看:37
本文介绍了Web 应用程序中的 NTLM 身份验证 (java)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下过滤器在我的 Web 应用程序中启用 NTLM 身份验证.

I am using following filter to enable NTLM Authentication, in my web-application.

我收到 Windows 浏览器身份验证提示.它工作正常.除了以下事实 - 我无法判断身份验证是成功还是失败!!! *在任何一种情况下都没有错误.* 在每种情况下,用户名(正确或否则),打印工作站等.

I get the windows browser authentication prompt. It is working fine. Except for the fact that - I am unable to tell if Authentication Succeeded or Failed !!! *There are no errors in either case.* In every case username(correct or otherwise), workstation etc. is printed.

package com.test;
import java.io.IOException;
import java.io.PrintStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jcifs.ntlmssp.Type3Message;
import com.sun.xml.internal.ws.util.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class NTLMUserFilter implements Filter {
    private FilterConfig filterConfig = null;
    private String userDomain = null;
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        String username = null;
        //first, get the user agent
        String useragent = request.getHeader("user-agent");
        //if you're using IE, you can continue
        if ((useragent.indexOf("MSIE") > -1)){
            //Always do the ntlm check (for IE POST back)
            try{
                String auth = request.getHeader("Authorization");
                if (auth == null)
                {
                  response.setHeader("WWW-Authenticate", "NTLM");
                  response.setStatus(response.SC_UNAUTHORIZED);
                  response.setContentLength(0) ;
                  response.flushBuffer();
                  return;
                }
                if (auth.startsWith("NTLM "))
                {
                  byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth.substring(5));
                  int off = 0, length, offset;
                  if (msg[8] == 1)
                  {
                    byte z = 0;
                    byte[] msg1 = {(byte)'N', (byte)'T', (byte)'L', (byte)'M', (byte)'S', (byte)'S', (byte)'P', z,(byte)2, z, z, z, z, z, z, z,(byte)40, z, z, z, (byte)1, (byte)130, z, z,z, (byte)2, (byte)2, (byte)2, z, z, z, z, z, z, z, z, z, z, z, z};
                    response.setHeader("WWW-Authenticate", "NTLM " + new sun.misc.BASE64Encoder().encodeBuffer(msg1));
                    response.setStatus(response.SC_UNAUTHORIZED);
                    response.setContentLength(0) ;
                    response.flushBuffer();
                    return;
                  }
                  else if (msg[8] == 3)
                  {
                      //Did Authentication Succeed? All this is always printed.

                      Type3Message type3 = new Type3Message(msg);

                      System.out.println("osUser: " + type3.getUser());
                      System.out.println("osRemoteHost: + " + type3.getWorkstation());
                      System.out.println("osDomain: " + type3.getDomain());

                  }
                }
            }catch(Exception e){
                System.out.println(e) ;
            }
            //System.out.println("Suc);


            }

        try {
            chain.doFilter(req, res);
        } catch (IOException e) {
            System.out.println(e);
        } catch (ServletException e) {
            System.out.println(e);
        }
    }
public void destroy()
   {
     this.filterConfig = null;
   }
}

<小时>

web.xml 很简单:


The web.xml is simple:

<filter>
    <filter-name>ntlmFilter</filter-name>
    <filter-class>
        com.test.NTLMUserFilter
    </filter-class>
</filter>

<!-- Filter mapping configuration   -->

<filter-mapping>
    <filter-name>ntlmFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>   

推荐答案

您收到了类型 3 的消息,但除了打印出详细信息之外,您并没有对其进行任何操作.此时您需要验证客户端的响应,然后发送 200(如果已授权)或 401(如果未授权).

You're receiving the Type 3 message, but you're not doing anything with it except printing out the details. You need to validate the client's response at this point and either send a 200 (if authorized) or a 401 (if not.)

然而,您传递的类型 1 消息由静态字节组成,并且 - 虽然它会导致客户端发回响应 - 几乎没有意义.自己实现一个完整的 NTLM 身份验证堆栈并非不可能,但您拥有的代码根本无法运行.

However the Type 1 message you delivered is made up of static bytes and - while it will induce a client to send back a response - is mostly meaningless. It's not impossible to implement a complete NTLM authentication stack yourself, but the code you have will simply not work.

您可以调查 Java 的 NTLM 解决方案,或者(假设您是在 Windows 上)您可以调用必要的身份验证功能,例如 AcceptSecurityContext 使用 JNI.

You could investigate an NTLM Solution for Java, or (assuming you're on Windows) you could call the necessary authentication functions like AcceptSecurityContext with JNI.

这篇关于Web 应用程序中的 NTLM 身份验证 (java)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆