当前位置: 首页 > 知识库问答 >
问题:

如果可用,通过Active Directory进行单点登录身份验证的最佳方法是什么?

周学义
2023-03-14

我们需要通过Active Directory进行身份验证。我们希望域内的Windows用户无需输入用户名和密码(单点登录)即可进行身份验证,但外部用户(或不使用Internet Explorer的用户)也能够插入他们的用户名和密码并登录。

我们还需要在用户所属的组中举手,因为这将改变用户在我们网站上看到的内容。

我们使用Java和Jetty作为应用服务器,并在Windows中开发,但我们的服务器将是Linux。

非常感谢。

共有3个答案

柯瀚海
2023-03-14

如果可以对外部用户进行身份验证,则可能需要在应用程序数据库中存储用户名(至少)。

您可以使用JNDI通过LDAP的AD实现来获取用户组信息(这也需要一些web.xml的标准条目)。

您可以通过JCIFS对Intranet上的内部AD用户使用NTLM身份验证。

基于这一假设:

>

公共静态布尔认证UsingJCIF(字符串用户名,字符串密码){

        UniAddress uniaddress = null;
        String _methodName = "authenticateUsingJCIF";
                try {
            uniaddress = UniAddress.getByName(PropertyUtils
                    .getProperty(AUTHENTICATION_SERVER_URL));
            NtlmPasswordAuthentication ntlmpasswordauthentication = new NtlmPasswordAuthentication(PropertyUtils.getProperty(AUTHENTICATION_SERVER_DOMAIN),username, password); //You can have your own method to read properties, I've just delegated to a generic utils
            SmbSession.logon(uniaddress, ntlmpasswordauthentication);
            logger.info("INTERNAL User authenticated successfully against AD");
        } catch (UnknownHostException e) {
            logger.error(e.toString(), e);
            return false;
        } catch (SmbException e) {
            logger.error(e.toString(), e);
            return false;
        } catch (Exception e) {
            logger.error(e.toString(), e);
            return false;
        }
        return true;
    }

对于外部用户有一个正常的用户名/密码验证:像这样

私有字符串身份验证外部用户(String id, YourUserNamePasswordAuthenticationSource AuthSource){String statusMessage=null;

    logger
            .info("Performing credential verification for external user against INTERNAL DB");
        //Create or utilize your own handlers to validate plain/encoded credentials against internal db
    CredentialVerificationResult returnCode = _handler
            .verifyInternalCredential(id, authSource.getPassword());
    logger.info("Logging value of return code" + returnCode.getMessage());
    if (returnCode == CredentialVerificationResult.SUCCESS) {
        statusMessage = CREDENTIAL_VERIFICATION_SUCCESS;
    } else if (returnCode == CredentialVerificationResult.BAD_USER_ID) {
        statusMessage = BAD_USER_ID;
    } else if (returnCode == CredentialVerificationResult.WAIT_TO_RETRY) {
        statusMessage = WAIT_TO_RETRY;
    } else if (returnCode == CredentialVerificationResult.CREDENTIAL_LOCKED) {
        statusMessage = CREDENTIAL_LOCKED;
    } else if (returnCode == CredentialVerificationResult.PASSWORD_MISMATCH) {
        statusMessage = PASSWORD_MISMATCH;
    }
    return statusMessage;
}

您可能希望有一个通用方法来验证内部/外部用户(调用上述2个方法)并相应地返回您的结果。

希望有帮助,祝你好运!

法和硕
2023-03-14

对于组个性化,Web应用程序需要知道用户来自哪里(Intranet或Internet),这可以通过标头、Apache中的IP范围配置等来完成——这取决于您的详细配置和代码。

对于Intranet SSO,您似乎需要SPNEGO,下面的链接。对于Intranet SSO,贵公司的管理策略和Internet Explorer设置将发挥重要作用,因此我将从页面复制清单:

  1. 使用主机名而不是IP集成访问服务器

http://wiki.eclipse.org/Jetty/Howto/Spnego

孔海超
2023-03-14

正如@Akber所建议的,您可以使用IP范围。您需要一个使用远程地址或X-Forwarded-For标头的公共endpoint,您可以使用IP测试它是否在Intranet范围内,这是10.0.0.0/8、172.16.0.0/12、192.168.0.0/12

如果IP位于intranet范围内,则可以重定向到Apache代理(稍后将详细介绍)。如果IP超出范围,则重定向到具有漂亮表单的endpoint。

带有mod_auth_kerb的Apache是我们在此场景Linux中唯一有效的方法之一。您可以将apache配置为kerberos代理,它将协商kerberos,然后使用标头调用您的后端。这是一个配置示例:

  ProxyPass        / http://localhost:9005/ #your backend
  ProxyPassReverse / http://localhost:9005/ #your backend
  ProxyPreserveHost On

  ## Rewrite rules
  RewriteEngine On
  RewriteCond %{LA-U:REMOTE_USER} (.+)
  RewriteRule . - [E=RU:%1]

  ## Request header rules
  ## as per http://httpd.apache.org/docs/2.2/mod/mod_headers.html#requestheader
  RequestHeader set X-Forwarded-User %{RU}e

  <Location />
     AuthName "Kerberos Login"
     AuthType Kerberos
     Krb5Keytab /path/to your keytab/HTTP.keytab
     KrbAuthRealm DOMAIN.LOC
     KrbMethodNegotiate on
     KrbSaveCredentials off
     KrbVerifyKDC off
     KrbServiceName HTTP/YOURAPP.AD2008R2.LOC
     Require valid-user
  </Location>

然后您的后端将收到X-Forwarded-User,您可以使用LDAP递归获取完整的配置文件和组。

请注意,您的keytab/HTTP有一个路径。keytab,此文件应从绑定到域的Windows计算机生成。

这由您的应用程序直接处理,一旦您收到用户名和密码,您将不得不尝试使用LDAP协议“绑定”到AD,然后您必须递归获取用户配置文件和组。

这看起来可能很简单,但实际上它涉及到您的许多工作,不仅是代码,还有维护。还有另外两种解决方案可能适用于您的情况,但需要部署另一种产品;

  • ADFS:是Microsoft的一种产品,可以部署在Windows服务器(IIS)中,使用AD进行身份验证,并与WS-Federation或SAML对话
  • Auth0:可以部署在本地,它作为虚拟设备(linux)提供。它可以使用任何身份提供者进行身份验证,当然包括AD。我们做了一些类似于我在这里描述的AD的事情,但在应用程序中,您不需要做任何事情,只需使用OAuth库或JWT验证库即可

免责声明:我为Auth0工作。

 类似资料:
  • 我们目前正在从遗留安全子系统迁移到Elytron,并在JBoss EAP 7.3.6中部署了一个基于Struts2的web应用程序,该应用程序应该支持多种“风格”的身份验证。 登录的标准方式应该是,用户以登录表单()手动提供凭据,然后单击相应的按钮。这在我们的设置中与Elytron配合得很好。 第二种可能性是,对Web应用程序受保护内容的GET请求可能包含包含JWT令牌的自定义cookie。这个c

  • 嗨,我正在进行Spring Boot,我正在尝试使用Spring Security性来从active Directory进行用户身份验证。但是我无法将用户登录到应用程序中,我已经尝试了几个东西,下面是我尝试的代码: 当我试图从administrator登录时,我得到的错误如下: 原因:LDAP处理过程中出现未分类异常;嵌套异常是javax.naming.namingException:[LDAP:

  • 如何在iOS8中使用CloudKit实现Sign sign-on? 我知道你可以得到一个代表你的登录用户的字符串,这是你的应用程序唯一的,但是我如何在我的后端验证那个字符串呢? 我明白Apple ID/iCloud电子邮件地址是出于隐私原因而隐藏的。 我的后端是Azure中的ASP.NET Web API2,但如果更简单的话,我可以用另一种技术实现它。 我正在寻找相当于谷歌在Android上的单点

  • 我正在尝试为自己构建一个仪表板,为我使用的一些应用程序提供基于SAML的身份验证。 从我作为测试平台构建的: 我正在使用一个登录名作为我要使用的应用程序的身份提供者。 举个例子:对于Netflix,我被重新路由到Netflix页面,我的用户ID和密码被预先填入其中,就像密码管理器的工作方式一样。(它使用OneLogin的扩展名) Netflix是否允许基于SAML的单点登录身份验证?我无法从谷歌搜

  • 问题: 我们有一个spring的基于MVC的RESTful API,它包含敏感信息。API应该是安全的,但是不希望在每个请求中发送用户的凭据(User/Pass组合)。根据REST指南(和内部业务需求),服务器必须保持无状态。API将由另一台服务器以混搭方式使用。 要求: > 客户端请求使用凭据(不受保护的URL);服务器返回一个安全令牌,该令牌包含足够的信息,供服务器验证未来的请求并保持无状态。

  • 我试图用注册时使用的凭证登录。Firebase已经有注册用户的条目。每次我试图登录它显示“登录不成功”,我没有看到任何代码问题。请帮帮忙。