Friday, April 27, 2012

Connecting to Active Directory from Java: Configuring an SSL Certificate for Microsoft Active Directory

If you wish to add users or change passwords in Active Directory from Java code, you will need to install an SSL certificate generated by your Active Directory server and then install the certificate into your JVM keystore.

The very first step to enable secure communication between Java and Active Directory is:

Installation of the Active Directory Certificate Services

This installs a certification authority (CA) which is used to issue certificates. Description below, explains this process. The screenshots below are scrapped from Server 2008R2 Polish language version, but visually English interface appears very simillar.

1. Log in to your Active Directory server as an administrator.
2. Click Start, point to Administrative Tools, and then click Server Manager.
3. In the Roles Summary section, click Add Roles.
4. On the Select Server Roles page, select the Active Directory Certificate Services check box. Click Next.
5. The Certification Authority instalation wizard appears. Click Next.

6. On the Select Role Services page, select the Certification Authority check box, and then click Next.

7. On the Specify Setup Type page, click Enterprise, and then click Next.

8. On the Specify CA Type page, click Root Certification Authority, and then click Next.

9. On the Set Up Private Key select Create new private key. Then click Next.

10. On the Configure Cryptography for CA you can select default values which should be ok in typical cases.

11. In the Common name for this CA box, type the common name of the CA, and then click Next.

12. On the Set Validity Period page, accept the default values, and then click Next.

13. On the Configure Certification Database page you can change default database and log location if you really need. Then click Next.

14. On the Confirm Installation Selections page you have selected settings summary. If all is ok, click Install.

15. Review the information on the results screen to verify that the installation was successful.

16. Restart the server.

Obtaining the Server Certificate

After installation of CA you need obtain Microsoft Active Directory server's SSL certificate to add it to the list of accepted certificates used by the JDK that runs your application or application server.

To export certificate you should run from command line:

certutil -ca.cert your_server_certificate.crt

Obtained file will be ready to import into JDK keystore.

Importing the Server Certificate

For an Java application to trust your Active Directory's certificate, it must be imported into your Java runtime environment default keystore. The JDK stores trusted certificates in a file called a jre\lib\security\cacerts in the root directory of your Java Development Kit installation.

To import certificate go to  jre\bin directory and run:

keytool -import -keystore ..\lib\security\cacerts -alias yourAlias -file c:\your_path\
your_server_certificate.crt

The keytool will prompt you for a password. The default keystore password is changeit.

Reslut of above operation is shown bellow:
When prompted Trust this certificate? [no]: enter yes to confirm the key import.

Next you can try connect to Active Directory drirectly from your Java application.

Thursday, April 26, 2012

How-to: applying JSF runtime configuration parameters in JSF 2.0

Servlet containers support application configuration parameters that may be customized by including <context-param> elements in the web application deployment descriptor.  Following application configuration parameter are supported in all JSF 2.0 implementations:


Param Name
javax.faces.CONFIG_FILES
Comma-delimited list of context-relative paths to faces config files. JSF application will load the files before loading default config file"/WEB-INF/faces-config.xml". If "/WEB-INF/faces-config.xml" is present in the list, it will be ignored.null1.2 and 2.0
javax.faces.DEFAULT_SUFFIX
Change the default suffix for JSP views. Allow the web application to define an alternate suffix for JSP pages containingJSF content..jsp1.2 and 2.0
javax.faces.LIFECYCLE_ID
ID for alternate Lifecycle implementations. Lifecycle identifier of the Lifecycle instance to be used when processing JSF requests for this web application. If not sp ecified, the JSF default instance, identified by LifecycleFactory.DEFAULT_LIFECYCLE, will be used.null1.2 and 2.0
javax.faces.STATE_SAVING_METHOD
The location where state information is saved. Valid values are “server” (typically saved in HttpSession ) and “client (typically saved as a hidden field in the subsequent form submit). If not specified, the default value “server” will be used.server1.2 and 2.0
javax.faces.DATETIMECONVERTER _DEFAULT_TIMEZONE_IS _SYSTEM_TIMEZONE
Controls if DateTimeConverter instances use the system timezone (if true) or GMT (if false).false2.0
javax.faces.DATETIMECONVERTER _DEFAULT_TIMEZONE_IS _SYSTEM_TIMEZONE
Controls if DateTimeConverter instances use the system timezone (if true) or GMT (if false).false2.0
javax.faces.DISABLE_FACELET_JSF_VIEWHANDLER
Disables the built-in Facelet ViewHandler. Useful for applications that use legacy Facelets implementation. If this param is set to "true", the default ViewHandler behaves as specified in the latest 1.2 version of JSF specification. Any behavior specified in Section 7.5 “ViewHandler” and implemented in the default ViewHandler that pertains to handling requests for pages authored in the JSF isn't executed by the runtime.false2.0
javax.faces.FACELETS_LIBRARIES
Semicolon-separated list of paths, starting with “/” (without the quot es), to Facelet tag libraries. The runtime interprets each entry in the list as a path relative to the web application root and interprets the file found at that path as a facelet tag library. null2.0
facelets.LIBRARIES
Semicolon-separated list of paths to Facelet tag libraries. Used for backward-compatibility with legacy Facelets implementation. Considered as an alias to javax.faces.FACELETS_LIBRARIES.null2.0
javax.faces.FACELETS_BUFFER_SIZE
The buffer size set on the response.-1 (no assigned buffer size)2.0
facelets.BUFFER_SIZE
The buffer size set on the response. Used for backward-compatibility with legacy Facelets implementation.-1 (no assigned buffer size)2.0
javax.faces.DECORATORS
Semicolon-delimited list of javax.faces.view.facelets.TagDecorator implementations. These decorators will be loaded when the first request for a Facelets VDL view hits the ViewHandler for page compilation. The runtime also considers the facelets.DECORATORS param name as an alias to this param name for backwards compatibility with existing facelets tag libraries.null2.0
facelets.DECORATORS
Semicolon-delimited list of TagDecorator implementations. Used for backward-compatibility with legacy Facelets implementation alias for javax.faces.DECORATORS.null2.0
javax.faces.FACELETS_REFRESH_PERIOD
Time in seconds that facelets should be checked for changes since last request. When a page is requested, what interval in seconds should the compiler check for changes. If you don't want the compiler to check for changes once the page is compiled, then use a value of -1. Setting a low refresh period helps during development to be able to edit pages in a running application.implementation-specific2.0
facelets.REFRESH_PERIOD
Time in seconds that facelets should be checked for changes since last request. A value of -1 disables refresh checking. Used for backward-compatibility with legacy Facelets implementation alias for javax.faces.FACELETS_REFRESH_PERIOD.implementation-specific2.0
javax.faces.FACELETS_RESOURCE_RESOLVER
An implementation of javax.faces.view.facelets.ResourceResolver. If this param is set, the runtime interprets its value as a fully qualified classname of a java class that extends javax.faces.view.facelets.ResourceResolver and has a zero argument public constructor or a one argument public constructor where the type of the argument is ResourceResolver. If this param is set and its value does not conform to those requirements, the runtime logs a message and continues. If it does conform to these requirements and has a one-argument constructor, the default ResourceResolver will be passed to the constructor. If it has a zero argument constructor it is invoked directly. In either case, the new ResourceResolver replaces the old onenull2.0
facelets.RESOURCE_RESOLVER
An implementation of javax.faces .view.facelets .ResourceResolver. Used for backward-compatibility with legacy Facelets implementation alias for javax.faces.FACELETS_RESOURCE_RESOLVER.null2.0
javax.faces.FACELETS_SKIP_COMMENTS
If set to "true", runtime strips XML comments out of Facelets before delivering to the client.false
facelets.SKIP_COMMENTS
If set to "true", JSF runtime strips XML comments out of Facelets before delivering to the client. Used for backward-compatibility with legacy Facelets implementation alias for javax.faces.FACELETS_SKIP_COMMENTS.false2.0
javax.faces.FACELETS_SUFFIX
Set the suffix for Facelet xhtml files..xhtml
facelets.SUFFIX
Set the suffix for Facelet xhtml files. Used for backward-compatibility with legacy Facelets implementation..xhtml
javax.faces.FACELETS_VIEW_MAPPINGS
Semicolon-separated list of Facelet files that don't use the default facelets suffix. If this param is set, the runtime interprets it as a semicolon (;) separated list of strings that is used to forcibly declare that certain pages in the application must be interpreted as using Facelets, regardless of their extension.null2.0
facelets.VIEW_MAPPINGS
Semicolon-separated list of Facelet files that don't use the default facelets suffix. Used for backward-compatibility with legacy Facelets implementation alias for javax.faces.FACELETS_VIEW_MAPPINGS.null2.0
javax.faces.FULL_STATE_SAVING_VIEW_IDS
Semicolon-separated list of view IDs that must save state using the JSF 1.2-style state saving.null
javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES _AS_NULL
If true, consider empty UIInput values to be null instead of empty string. If the javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL context parameter value is true (ignoring case), and UIInput.getSubmittedValue() returns a zero-length String call UIInput.setSubmittedValue(null) and continue processing using null as the current submitted value.false2.0
javax.faces.PARTIAL_STATE_SAVING
If true, use the JSF2 partial state saving for views. For previous versions has no effects.false, if WEB-INF/faces-config.xml does not declare JSF 2.0 schema. true, otherwise2.0
javax.faces.PROJECT_STAGE
A human readable string describing where this particular JSF application is in the software development lifecycle. Set the project stage to "Development", "UnitTest", "SystemTest", or "Production". It is also possible to set this value via JNDI. See the javadocs for Application.getProjectStage().Production2.0
javax.faces.SEPARATOR_CHAR
The context param that allows the character used to separate segments in a UIComponent clientId to be set on a per-application basis.null, interpreted as default (:) value2.0
javax.faces.VALIDATE_EMPTY_FIELDS
If "true" all submitted fields will be validated. This is necessary to allow the model validator to decide whether null or empty values are allowable in the current application. If the value is "false", null or empty values will not be passed to the validators. If the value is the string “auto”, the runtime will check if JSR-303 Beans Validation is present in the current environment. If so, the runtime will proceed as if the value “true” had been specified. If JSR-303 Beans Validation is not present in the current environment, the runtime will proceed as if the value “false” had been specified. If the param is not set, the system behaves as if the param was set with the value “auto”.auto2.0
javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR
If "true", disable JSR-303 Bean Validation, and If this param is set, eg. the runtime will not automatically add the validator with validator-id equal to the value of the symbolic constant javax.faces.validator.VALIDATOR_ID to the list of default validators. Setting this parameter to true will have the effect of disabling the automatic installation of Bean Validation to every input component in every view in the application, though manual installation is still possible.false2.0

The JSF engine parameters are case sensitive. If the value specified for a parameter is comprised of two or more words separated by spaces, you must add quotation marks around the value.

You have here a simple example of use of configuration parameters:
<context-param>
         <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
         <param-value>.abc</param-value>
</context-param> 

In addition to the parameters neutral terms of JSF implementation, there exist also implementation specific parameters for Mojarra, MyFaces and so on.

How to: Save PL/SQL query results to text file

The my solution is very simple, without use of often suggested on forums solutions based on UTL_FILE package. To solve this problem I simply used the database spool functionality. Please check out code cited below:

SET ECHO OFF FEEDBACK OFF;
SET COLSEP ',';
SPOOL c:/oracle/myOutputFile.txt;
SELECT samaccname,nextcolumn from mytable where samaccname is not null;
SPOOL OFF;

Thursday, April 19, 2012

Webcenter Content folders: how to get Folder ID (Collection ID)

The JCR standard uses a hierarchical data model based on extensible node types and content properties. 
In Java JCR repositories nt:folder node type represents a structured collection of nodes. It is closely related to the directory or folder concept found in many file systems and is the node type that is normally used when mapping file system directories to a content repository.

Generally UCM Folder concept is functionally similar, but really Webcenter Content Folder is more virtual. Phisically it is an additional document type, and folder name is mapped to metadata represented by long integer value.

Returning to our problem. You can find help in Oracle® WebCenter Content Services Reference Guide, chapter 7.2.40 COLLECTION_INFO :) But if you need sample, you have one bellow.

 try{
    DataBinder request = idcClient.createBinder();
    request.putLocal("IdcService", "COLLECTION_INFO");
    request.putLocal("hasCollectionPath", "true");
    request.putLocal("dCollectionPath", path);
    
    ServiceResponse response = idcClient.sendRequest(userContext, request);
    DataBinder binder = response.getResponseAsBinder();
    DataResultSet rs = binder.getResultSet("PATH");
    DataObject da = rs.getRows().get(rs.getRows().size() - 1);
    Long folderID = new Long(da.get("dCollectionID"));
    return folderID;
    }
    catch...

Wednesday, April 18, 2012

How to change Windows 2008 domain name

Regarding my previous post: How to recover domain when the primary domain controller failes and there are member domain controller, one of my readers asked me, how to change domain name.

The idea was to transfer full AD database via:
  • adding new DC to domain, 
  • replicate database
  • disconnect new DC and "recover" it to fully functional DC following my recipe,
  • and finally rename our "new" domain to avoid conflicts with old one 
To rename domain you should use Domain Rename tool as described here: http://technet.microsoft.com/en-us/library/cc781575%28v=ws.10%29.aspx.

In near future I will check this method and write few words about effects of my experiment.

Saturday, April 14, 2012

UCM Error: EMLoadMap() failed: error opening template file (061C)

Today I had next unexpected UCM Dynamic Converter error:

!csUserEventMessage,weblogic,ucmhost:16200!csFileServiceReferredToBy,http://ucmhost:16200/cs/idcplg?IdcService=GET_DYNAMIC_CONVERSION&dID=614!csFileServiceUserAgent,Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0,GET!csFailedToExport,000614,,!csExportProcess,hcexport
intradoc.common.ServiceException: !csFailedToExport,000614,,!csExportProcess,hcexport
*ScriptStack GET_DYNAMIC_CONVERSION_SUB
3:doSubService,dID=614,dDocName=000614GET_DYNAMIC_CONVERSION_SUB,dID=614,dDocName=0006143:runHtmlConversion,dID=614,dDocName=000614
at dynamicconverter.DynConverterHandler.doConversion(DynConverterHandler.java:1422)
at dynamicconverter.DynConverterHandler.runHtmlConversion(DynConverterHandler.java:1125)
at sun.reflect.GeneratedMethodAccessor9853.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at intradoc.server.ServiceHandler.executeAction(ServiceHandler.java:79)
at intradoc.server.Service.doCodeEx(Service.java:533)
at intradoc.server.Service.doCode(Service.java:506)
at intradoc.server.ServiceRequestImplementor.doAction(ServiceRequestImplementor.java:1643)
at intradoc.server.Service.doAction(Service.java:477)
at intradoc.server.ServiceRequestImplementor.doActions(ServiceRequestImplementor.java:1458)
at intradoc.server.Service.doActions(Service.java:473)
at intradoc.server.ServiceRequestImplementor.executeSubServiceCode(ServiceRequestImplementor.java:1323)
at intradoc.server.Service.executeSubServiceCode(Service.java:3867)
at intradoc.server.ServiceRequestImplementor.executeServiceEx(ServiceRequestImplementor.java:1200)
at intradoc.server.Service.executeServiceEx(Service.java:3862)
at intradoc.server.Service.executeService(Service.java:3846)
at intradoc.server.Service.doSubService(Service.java:3761)
at sun.reflect.GeneratedMethodAccessor9638.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at intradoc.server.Service.doCodeEx(Service.java:550)
at intradoc.server.Service.doCode(Service.java:506)
at intradoc.server.ServiceRequestImplementor.doAction(ServiceRequestImplementor.java:1643)
at intradoc.server.Service.doAction(Service.java:477)
at intradoc.server.ServiceRequestImplementor.doActions(ServiceRequestImplementor.java:1458)
at intradoc.server.Service.doActions(Service.java:473)
at intradoc.server.ServiceRequestImplementor.executeActions(ServiceRequestImplementor.java:1391)
at intradoc.server.Service.executeActions(Service.java:458)
at intradoc.server.ServiceRequestImplementor.doRequest(ServiceRequestImplementor.java:737)
at intradoc.server.Service.doRequest(Service.java:1890)
at intradoc.server.ServiceManager.processCommand(ServiceManager.java:435)
at intradoc.server.IdcServerThread.processRequest(IdcServerThread.java:265)
at intradoc.idcwls.IdcServletRequestUtils.doRequest(IdcServletRequestUtils.java:1346)
at intradoc.idcwls.IdcServletRequestUtils.processFilterEvent(IdcServletRequestUtils.java:1715)
at intradoc.idcwls.IdcIntegrateWrapper.processFilterEvent(IdcIntegrateWrapper.java:222)
at sun.reflect.GeneratedMethodAccessor9625.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at idcservlet.common.IdcMethodHolder.invokeMethod(IdcMethodHolder.java:88)
at idcservlet.common.ClassHelperUtils.executeMethodEx(ClassHelperUtils.java:305)
at idcservlet.common.ClassHelperUtils.executeMethodWithArgs(ClassHelperUtils.java:278)
at idcservlet.ServletUtils.executeContentServerIntegrateMethodOnConfig(ServletUtils.java:1600)
at idcservlet.IdcFilter.doFilter(IdcFilter.java:352)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:57)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:111)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:413)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:94)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:161)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:57)
at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:136)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:57)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:111)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:413)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:94)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:161)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:57)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

followed by:

EMLoadMap() failed: error opening template file (061C).


My UCM was installed in cluster architecture, on Windows 2008 R2 machines.
After few hours googling I found ... nothing.

I thought that there are some IO problems, but after reviewing security privileges also haven't found any issues.
After analyzing logs once again I drew my attention to the process hcexport. As I noticed, it is an external Windows application called directly from java code.
So I started searching for this application and then re-analyzed possible problems: library dependencies, rights, call parameters and I found !!!

The cause of the problem was trivial. We had UCM configuration error. Some paths in config file was defined in "quasi unix", Oracle recommended, manner:

D:/Oracle/FMW/user_projects/....

It works properly, but paths defined as:

//nas_store/ucm_cluster/.....

can't be resolved properly by Windows application, cause they don't comply UNC Name Syntax. The right notation should look like:
\\nas_store\whateever

and finally in translating to the Java path style recommended by Oracle:

\\\\nas_store/ucm_cluster/.....