среда, 28 июля 2010 г.

Доступ к AD(LDAP) для Application приложений

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class LDAPTest
{
static class LDAP
{
static String ATTRIBUTE_FOR_USER = "sAMAccountName";
public Attributes authenticateUser(String username, String password, String _domain, String host, String dn)
{

String returnedAtts[] ={ "sn", "givenName", "mail" };
String searchFilter = "(&(objectClass=user)(" + ATTRIBUTE_FOR_USER + "=" + username + "))";
//Create the search controls

SearchControls searchCtls = new SearchControls();
searchCtls.setReturningAttributes(returnedAtts);
//Specify the search scope

searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String searchBase = dn;
Hashtable environment = new Hashtable();
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
//Using starndard Port, check your instalation

environment.put(Context.PROVIDER_URL, "ldap://" + host + ":389");
environment.put(Context.SECURITY_AUTHENTICATION, "simple");

environment.put(Context.SECURITY_PRINCIPAL, username + "@" + _domain);
environment.put(Context.SECURITY_CREDENTIALS, password);
LdapContext ctxGC = null;
try
{
ctxGC = new InitialLdapContext(environment, null);
// Search for objects in the GC using the filter

NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);
while (answer.hasMoreElements())
{
SearchResult sr = (SearchResult)answer.next();
Attributes attrs = sr.getAttributes();
if (attrs != null)
{
return attrs;
}
}

}
catch (NamingException e)
{
System.out.println("Just reporting error");
e.printStackTrace();
}
return null;
}
}

public static void main(String[] args) throws Exception
{
InputStreamReader converter = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(converter);
System.out.println("Please type username:");
String username = in.readLine();
System.out.println("Please type password:");
String password = in.readLine();
LDAP ldap = new LDAP();

//Yo specify in the authenticate user the attributes that you want returned

//Some companies use standard attributes like 'description' to hold an employee ID

//The ActiveDirectory data can be enhanced to add custom attributes like

//printer

// Some instalations usually have several ACtiveDirectoryServers, lets say

// 192.150.0.8, 192.150.0.7 y 192.150.0.9 and they use a

// DNS round robin to balance the load

Attributes att = ldap.authenticateUser(username, password, "mydomain.com", "myactivedirectoryhost.com", "DC=mydomain,DC=com");
if (att == null)
{
System.out.println("Sorry your use is invalid or password incorrect");
}
else
{
String s = att.get("givenName").toString();
System.out.println("GIVEN NAME=" + s);
}
}
}

Авторизация в JSF2 через Active Derectory, GlassFish v 3.0.1 (LDAP)

Задача: Оргонизовать авторизацию пользователей через MS Active Derectory
Инструменты: GlassFish v3.0.1 OpenSource, NetBeans 9, CentOS 5.5

Настрйока GlassFish
Через web админку, заходим в rootTree > configuretion > Security > Realms
Создаем новый Realm нажатием кнопки New
заполняем поля:

Realm Name:svel <Имя которое будет использоватся в дальнейшем контесте>
Class Name:com.sun.enterprise.security.auth.realm.ldap.LDAPRealm
JAAS Context:ldapRealm <Имя метода который мы используем fileRealm, ldapRealm и т.д.>
ldapRealm:ldap://192.168.0.1:389 <Адрес машины с AD или LDAP>
Base DN:DC=svel,DC=ru <указываем данные домена у меня он выглядит как svel.ru>

Далее добавляем 4 свойства
search-filter:(&(objectClass=user)(sAMAccountName=%s)) <Поиск пользователей в домене в обекте user в поле sAMAccountName>
search-bind-password:MyPassword <Пароль учетной записи имеющей доступ в AD или LDAP>
group-search-filter:(&(objectClass=group)(member=%d)) <Поиск групп пользователей в обекте group в поле member>
search-bind-dn:MyUser <Учетная запись имеющая права доступа в AD или LDAP>

P.S: некоторые параметры могут менятся в зависимости от использования AD(LDAP)
Список свойств :
search-bind-password = (optional) Specifies the LDAP password for the DN given in search-bind-dn .
search-bind-dn = (optional) Specifies an optional DN used to authenticate to the directory for performing the search-filter lookup. Only required for directories that do not allow anonymous search.
group-target = (optional) Specifies the LDAP attribute name that contains group name entries. The default is CN.
group-search-filter = (optional) Specifies the search filter to find group memberships for the user. The default is uniquemember=%d (%d expands to the user element DN).
group-base-dn = (optional) Specifies the base DN for the location of groups data. By default, it is same as the base-dn, but it can be tuned, if necessary.
search-filter = (optional) Specifies the search filter to use to find the user. The default is uid=%s (%s expands to the subject name).
base-dn =
Specifies the LDAP base DN for the location of user data. This base DN can be at any level above the user data, since a tree scope search is performed. The smaller the search tree, the better the performance.
directory = Specifies the LDAP URL to your server.
assign-groups = (optional) If this property is set, its value is taken to be a comma-separated list of group names. All clients who present valid certificates are assigned membership to these groups for the purposes of authorization decisions in the web and EJB containers.
jaas-context = Specifies the JAAS (Java Authentication and Authorization Service) context.

Также необходимо в JVM Options добавить свойство
-Djava.naming.referral=follow

Выборка из конфига domain.xml

< auth-realm classname="com.sun.enterprise.security.auth.realm.certificate.CertificateRealm" name="certificate" />
< auth-realm name="svel" classname="com.sun.enterprise.security.auth.realm.ldap.LDAPRealm">
< property name="jaas-context" value="ldapRealm" />
< property name="base-dn" value="DC=svel,DC=ru" />
< property name="directory" value="ldap://192.168.0.2:389" />
< property name="search-bind-password" value="MyPassword" />
< property name="search-bind-dn" value="MyUser" />
< property name="search-filter" value="(&(objectClass=user)(sAMAccountName=%s))" />
< property name="group-search-filter" value="(&(objectClass=group)(member=%d))" />


Конфигурирование WebApp
в web.xml

на вкладке Security выбрать тип Basic в поле RealName: svel

В пункте Security Roles добавляем роли которые используются ввашем домене в качестве CN (CN=(350) Automation department)
я указываю (350) Automation department

В пункте Security Constraints
заполняем поля и в аоле Role Name(s) указываем те роли из указанных выше, которые имеют доступ к данному разделу безопасности.

пример кода их web.xml

< security-constraint>
< display-name>Constraint1< /display-name>
< web-resource-collection>
< web-resource-name>a< /web-resource-name>
< description/>
< url-pattern>/*< /url-pattern>
< /web-resource-collection>
< auth-constraint>
< description/>
< role-name>(350) Automation department< /role-name>
< /auth-constraint >
< user-data-constraint >
< description/ >
< transport-guarantee>NONE< /transport-guarantee>
< /user-data-constraint >
< /security-constraint >
< login-config >
< auth-method>BASIC< /auth-method>
< realm-name>svel< /realm-name>
< /login-config>
< security-role>
< description/>
< role-name>(350) Automation department< /role-name>
< /security-role>


Деплойтим и пользуемся :)

P.S:Для полноценной работы с Realm советую прочитать раздел Users, Role, Realms из JavaEETutorial

и еще проверить работает ли, можно прописав в index.xhtml данные строки

Для бейсик авторизации
< h:outputText value="#{request.isUserInRole('OU=(350) Отдел автоматизации')} " /> /-
< h:outputText value="#{request.isUserInRole('(350) Automation department')} " /> /-
< h:outputText value="#{request.getPathInfo()} " />/-
< h:outputText value="#{request.getRemoteUser()} " />

для авторизации через фонму добавте
< form action="j_security_check" method="POST">
< h:panelGrid columns="2" bgcolor="#eff5fa" cellspacing="5" frame="box">
< h:outputLabel value="User ID:"/>
< h:inputText id="j_username" tabindex="1" />
< h:outputLabel value="Password:"/>
< h:inputSecret id="j_password"/>
< h:outputLabel value=""/>
< h:commandButton id="login" value="Login"/>
< /h:panelGrid>
< /form>

полезные линки
не которы команды AD(LDAP)
еще
еще