Saturday, October 9, 2010

UCM Security - Need To Know component - sample step by step implementation

Guys,

Recently I came across a requirement which had to restrict the standard UCM Content Server security for few documents. Luckily we found there was already a component provided by Oracle just for that purpose (either to extend or restrict the standard security) named Need To Know.

This component can be downloaded from the Oracle website. Although there was a complete sixty page document for this component, it was no cakewalk for me to get it working. I tried to google but no luck, not much has been written about this component in the internet. So, I thought of writing one and sharing my experience.

The Need to Know component supports customization for Content Security, Search Results, Hit list roles, Content metadata security, and WHERE clause calculation. I will touch upon the Content Security part in this article.

The Need to Know component works on Security Group.

Lets get started with a sample requirement.
Consider a sample UCM application which has three security groups namely "SECGRP1", "SECGRP2" and "CONF_SECGRP". Accounts are enabled (about which we don't bother for this requirement). The requirement is to restrict access to some of the documents belonging to the Security Group "CONF_SECGRP". Even if user "A" has read permission on "CONF_SECGRP" as per standard security, we need to restrict it based upon some query given during check-in or update of the document.

Step 1 - Installation : Install the "Need to Know"(NTK) Component using either Component Manager or Component Wizard. Enable it.

Step 2 - Configuration :
a) Open the Admin Server Page and click the General Configuration link.
b) Under the "Additional Configuration Variables" heading, add the below
entry at the end of the text area.
SpecialAuthGroups=conf_secgrp
Only the security groups specified in the SpecialAuthGroups variable will use
the NTK component. Other security groups will have standard security applied.
c) Add a new metadata field that will be used for content-item level queries
(remember our requirement - restrict users based upon some value).
Add the new metadata field using the Configuration Manager. Use any field
name you wish. Here we name it as "DocDisclosureQuery". The field type
should be "memo". After adding the field, click Update Database Design.
d) Add a hit list role using the User Admin Applet. Create two roles "hitlist-r"
and "hitlist". Give read access to "CONF_SECGRP" for the role hitlist-r and
write access to "CONF_SECGRP" for the role hitlist. Do not assign this role
to any user.
e) Restart the content server.

Step 3 - NTK Administration : In the administration tab, you must be able to see a link for NTK component administration - NTK Configuration Information. Click on that link. NTK Administration screen looks as below.



Now we need to configure the new metadata field and hit list roles that we created in the last step.

a) Configuring the DocDisclosure field :

Click Edit button on the top right corner and select "Content Security Configuration Information" link. Scroll to the bottom of the page, in the
"Other Options" section, select the new metadata field that was created as the Disclosure Field and click Update.


b) Configuring the Hit List Role :

Click Edit button on the top right corner and select "Hit List Roles Configuration Information" link. Select "hitlist-r" role as Query Role and "hitlist" role as Update Role and click Update.



c) Limiting Access :

In the "Content Security Configuration Information" page, under the "Read Options" section, select "Yes" for both "Use Security" and "Limit Access". Since our requirement is to limit read access, we did the above configuration only in the "Read Options" section.

In the "Script" text area, write the below script which will determine the read access, based upon the content-item level query given during check-in or update of the document.

<$if isDisclosureQuery(xDocDisclosureQuery)$>
<$isNTKReadAccess=1$>
<$endif$>

Click Update button.


Now the NTK Configuration Information Page should appear as below reflecting the configurations done till now.



Step 4 : Click the "New Check In" link in the top menu and in the Content Check In form now a new metadata field for DocDisclosureQuery will appear along with a "update" button adjacent besides it.



The DocDisclosureQuery applet will be loaded by clicking the update button adjacent to the DocDisclosureQuery field. This applet will contain all the user attributes which can be used to form a content item level query that determines the access on top of standard security.

Step 5 - Check-in a document :
We are all set to check-in a document, specify a content level query and check whether all this works.

Click "New Check In" link in the menu.
1) Give the title of the document.
2) Select the Security Group - the one that is specified in SpecialAuthGroups.
3) Browse the document.
4) Enter all other metadata as per your application.

5) Content Item Level Query :
Click the Update button adjacent to the DocDisclosureQuery field. In the applet
select the "Field" as "Username", "Operator" as "Is" and Value as should be allowed to view this document>. Click Add button. The query
"Username is selvam" appears in the "Query Expression" text area.
You can form complex queries by making use of different user attributes and the
Add, Update and Merge buttons in the applet. For our example we will stick with
one user attrubute to form the query - Username.



Click Append button. The query should now appear in the DocDisclosureQuery field text area as below. You can even directly edit the query in the DocDisclosureQuery field text area.



Click "Check In". The document is successfully checked in now.

Step 6 - Testing the NTK security :
Login using user "selvam" and try to access the above checked-in document. This user must be able to view the content information page of the document.

Login using any other user who have read access to "CONF_SECGRP" other than "selvam" and try to access the document. "Insufficient Access Privilege" error will be thrown.

This is a very simple example of extending standard UCM security using NTK component.

There is one other thing to be noted here. If in your application, the virtual folders belong to the security group specified in the SpecialAuthGroups, and if the Read Access is limited using NTK component, then users won't be able to view the folders. There will be number of ways to overcome this problem. I did it the following way. There is a filter called "checkExtendedSecurityModelDocAccess". NTK makes use of this filter to extend the standard UCM security. The actual class implementing this filter is "NTKFilter" in the NTK component. So you can override this filter in such a way that the NTK security is not applied for the COLLECTION related services.

Hope this post serves as a good starting point to extend Standard UCM security using NTK component.

Good day..

Sunday, September 5, 2010

Autocomplete feature not working in eclipse

If the auto complete feature is not working in eclipse, then check the below setting in eclipse.

Go to Windows->Preferences->Java->Editor->Content Assist->Advanced and check whether the option "Other Java Proposals(Focused)" is checked or not.

If this option is not ticked, then tick that option. This shall resolve the problem.

Friday, August 27, 2010

Radio Button Functionality in Check boxes

Sometimes we need to implement the functionality of radio buttons using check boxes. It is very rare, but then...... This is just a very simple example..

<HTML>
<HEAD>
<script language='Javascript'>

function disableCheckbox(form)
{
var count = 0;
var loc = "";
var table = document.getElementById('table1');
var rows = table.getElementsByTagName("tr");
if(form.chks.length)
{
for (var j=0;j<form.chks.length;j++)
{
if (form.chks[j].checked)
{
count = 1;
loc = j;
break;
}
}
if(count == 1)
{
for(var j=0;j<form.chks.length;j++)
{
if(j != loc)
{
form.chks[j].disabled='true';
}
else
{
rows[j].className="shaded";
}
}
}
if(count == 0)
{
for(var j=0;j<form.chks.length;j++)
{
form.chks[j].checked=false;
form.chks[j].disabled=false;
rows[j].className="notshaded";
}
}
}
else
{
if(form.chks.checked)
rows[0].className="shaded";
else
rows[0].className="notshaded";
}
}

</script>

<style>
.notshaded {background-color: "#ffffff";}
.shaded{background-color: "#E8E8E8";}
</style>

</HEAD>

<BODY>

<form>

<table id='table1' border="1">

<tr>
<td>
<input type="checkbox" name="chks" value="first" onclick="disableCheckbox(this.form);" disabled='true'/>
</td>
<td>First</td>
</tr>

<tr class="shaded">
<td>
<input type="checkbox" name="chks" value="second" onclick="disableCheckbox(this.form);" checked="true"/>
</td>
<td>Second</td>
</tr>

<tr>
<td>
<input type="checkbox" name="chks" value="third" onclick="disableCheckbox(this.form);" disabled='true'/>
</td>
<td>Third</td>
</tr>

</table>
</form>

</BODY>
</HTML>

Saturday, November 21, 2009

UCM Content Server Error

Sometimes UCM Content Server doesnot start when you attempt to start it. If the error is one of the below, then it is because some other service is already listening on that port. So kill that process and the content server will start sweetly.

Follow my earlier post "How to find the process which is using a port" or do a google search on how to find the process which is already listening on a port.

After you the find the process listening on the port that content server is attempting to listen kill that process and then start the content server.
It should be java.exe.

*********************************************************
C1Node1: Unable to start the providers for 'Idc Content Service idc'. Unable to start the system provider 'SystemServerSocket'. Could not listen on address 10.102.65.46 port 4444. java.net.BindException: Address already in use: JVM_Bind [ Details ]
An error has occurred. The stack trace below shows more information.

!$C1Node1: !csUnableToStartProviders,Idc Content Service idc!csProviderUnableToStartSystem,SystemServerSocket!csCouldNotListen,10.102.65.46,4444!syExceptionType2,java.net.BindException,Address already in use: JVM_Bind
intradoc.common.ServiceException: !csProviderUnableToStartSystem,SystemServerSocket
at intradoc.server.IdcSystemLoader.prepareStartMonitorProviders(IdcSystemLoader.java:2104)
at intradoc.server.IdcManagerBase.startProviders(IdcManagerBase.java:67)
at intradoc.server.IdcManagerBase.serviceStart(IdcManagerBase.java:297)
at intradoc.server.IdcServerManager.serviceStart(IdcServerManager.java:170)
at IdcServerNT.init(IdcServerNT.java:87)
at IdcServerNT.main(IdcServerNT.java:54)
Caused by: intradoc.data.DataException: !csCouldNotListen,10.102.65.46,4444
at intradoc.provider.SocketIncomingProvider.startProvider(SocketIncomingProvider.java:255)
at intradoc.provider.Provider.startProvider(Provider.java:83)
at intradoc.provider.Provider.startProvider(Provider.java:76)
at intradoc.server.IdcSystemLoader.prepareStartMonitorProviders(IdcSystemLoader.java:2081)
... 5 more
Caused by: java.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
at java.net.ServerSocket.bind(ServerSocket.java:319)
at intradoc.provider.SocketIncomingProvider.createServerSocket(SocketIncomingProvider.java:544)
at intradoc.provider.SocketIncomingProvider.startProvider(SocketIncomingProvider.java:235)
**********************************************************

C1Node1: Failed to initialize the server. Unable to start the system provider 'SystemServerSocket'. Could not listen on address 10.102.65.46 port 4444. java.net.BindException: Address already in use: JVM_Bind [ Details ]
A fatal error has occurred. The stack trace below shows more information.

!$C1Node1: !csFailedToInitServer!csProviderUnableToStartSystem,SystemServerSocket!csCouldNotListen,10.102.65.46,4444!syExceptionType2,java.net.BindException,Address already in use: JVM_Bind
intradoc.common.ServiceException: !csProviderUnableToStartSystem,SystemServerSocket
at intradoc.server.IdcSystemLoader.prepareStartMonitorProviders(IdcSystemLoader.java:2104)
at intradoc.server.IdcManagerBase.startProviders(IdcManagerBase.java:67)
at intradoc.server.IdcManagerBase.serviceStart(IdcManagerBase.java:297)
at intradoc.server.IdcServerManager.serviceStart(IdcServerManager.java:170)
at IdcServerNT.init(IdcServerNT.java:87)
at IdcServerNT.main(IdcServerNT.java:54)
Caused by: intradoc.data.DataException: !csCouldNotListen,10.102.65.46,4444
at intradoc.provider.SocketIncomingProvider.startProvider(SocketIncomingProvider.java:255)
at intradoc.provider.Provider.startProvider(Provider.java:83)
at intradoc.provider.Provider.startProvider(Provider.java:76)
at intradoc.server.IdcSystemLoader.prepareStartMonitorProviders(IdcSystemLoader.java:2081)
... 5 more
Caused by: java.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
at java.net.ServerSocket.bind(ServerSocket.java:319)
at intradoc.provider.SocketIncomingProvider.createServerSocket(SocketIncomingProvider.java:544)
at intradoc.provider.SocketIncomingProvider.startProvider(SocketIncomingProvider.java:235)

How to find which process is using a port in Windows

The netstat command is used to display the TCP/IP network protocol statistics and information.

For help and to find all the options available with netstat command execute the below command.
c:/>netstat /?

To find all the open ports and which process is listening on those ports in Windows 2003 server follow the below steps.

Go to command prompt and type netstat -ano
It gives you the result of all active process running on the system along with the port to which they listen.

Then once you get the process id(PID) from the above step,
Go to Task Manager -> Processes tab.
Click View Menu -> Select Columns..
And select the check box of PID so that it gets displayed on the Processes tab.
Now using the PID got from the first step, get the process name which is listening on a particular port.

Monday, September 21, 2009

Ebooks

Books of every technology is available for free in this site in pdf format.
www.flazx.com

Tuesday, September 8, 2009

Servlet and Jsp Version and Server Information

Servlet and Jsp Version and also the Server information such as name and version that is being used can be obtained using the follwing code.

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspFactory;

public class VersionServlet extends HttpServlet {

protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {

PrintWriter out = response.getWriter();

//Servlet Version
//getMajorVersion() -> Returns the major version of the Java Servlet API that this servlet container supports.
//getMinorVersion() -> Returns the minor version of the Servlet API that this servlet container supports.
out.println("Servlet Version " +
this.getServletContext().getMajorVersion() + "." +
this.getServletContext().getMinorVersion());

//Jsp Version
out.println("Jsp Version " +
JspFactory.getDefaultFactory().getEngineInfo().
getSpecificationVersion());

//ServerInformation
//getServerInfo -> Returns the name and version of the servlet container on which the servlet is running.
out.println("Server Info " + this.getServletContext().getServerInfo());


}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}

}