我们需要通过Active Directory进行身份验证。我们希望域内的Windows用户无需输入用户名和密码(单点登录)即可进行身份验证,但外部用户(或不使用Internet Explorer的用户)也能够插入他们的用户名和密码并登录。
我们还需要在用户所属的组中举手,因为这将改变用户在我们网站上看到的内容。
我们使用Java和Jetty作为应用服务器,并在Windows中开发,但我们的服务器将是Linux。
非常感谢。
如果可以对外部用户进行身份验证,则可能需要在应用程序数据库中存储用户名(至少)。
您可以使用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个方法)并相应地返回您的结果。
希望有帮助,祝你好运!
对于组个性化,Web应用程序需要知道用户来自哪里(Intranet或Internet),这可以通过标头、Apache中的IP范围配置等来完成——这取决于您的详细配置和代码。
对于Intranet SSO,您似乎需要SPNEGO,下面的链接。对于Intranet SSO,贵公司的管理策略和Internet Explorer设置将发挥重要作用,因此我将从页面复制清单:
http://wiki.eclipse.org/Jetty/Howto/Spnego
正如@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,然后您必须递归获取用户配置文件和组。
这看起来可能很简单,但实际上它涉及到您的许多工作,不仅是代码,还有维护。还有另外两种解决方案可能适用于您的情况,但需要部署另一种产品;
免责声明:我为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已经有注册用户的条目。每次我试图登录它显示“登录不成功”,我没有看到任何代码问题。请帮帮忙。