Programmatically authenticate user in TAI

1.5k views Asked by At

I'm developing TAI which have to authorize user in WebSphere Portal.

My TAI using OpenID Connect gets all information about user and i want to build some context, give it to WAS and tell WAS that he has to trust for this context without local account.

How i can auth user in TAI without user account in local repositories?

UPDATE:

Code:

String userid = "bob";
String uniqueid = "bob";

Hashtable hashtable = new Hashtable();
hashtable.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, uniqueid);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, userid);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_CACHE_KEY, uniqueid+"MyCustom");

Subject subject = new Subject();
subject.getPublicCredentials().add(hashtable);
return TAIResult.create(HttpServletResponse.SC_OK, "ignored", subject);

Log:

[25.03.15 20:16:33:521 AMT] 00000043 ServiceLogger I com.ibm.ws.ffdc.IncidentStreamImpl initialize FFDC0009I: FFDC opened incident stream file  WebSphere_Portal_00000043_15.03.25_20.16.33_0.txt
[25.03.15 20:16:33:537 AMT] 00000043 ServiceLogger I com.ibm.ws.ffdc.IncidentStreamImpl resetIncidentStream FFDC0010I: FFDC closed incident stream file WebSphere_Portal_00000043_15.03.25_20.16.33_0.txt
[25.03.15 20:16:33:677 AMT] 00000043 StorageApi    E com.ibm.wps.policy.commands.StorageApi StorageApi EJQAB0064E: A Null argument was passed to the StorageApi constructor.
[25.03.15 20:16:33:724 AMT] 00000043 PolicyService E com.ibm.wps.policy.services.PolicyService Error Occured while creating storageAPI EJQAB0064E: A Null argument was passed to the StorageApi constructor.

FFDC:

------Start of DE processing------ = [3/25/15 20:16:33:474 AMT] , key = com.ibm.websphere.wim.exception.PropertyNotDefinedException com.ibm.ws.security.auth.ContextManagerImpl.runAs 4153
Exception = com.ibm.websphere.wim.exception.PropertyNotDefinedException
Source = com.ibm.ws.security.auth.ContextManagerImpl.runAs
probeid = 4153
Stack Dump = com.ibm.websphere.wim.exception.PropertyNotDefinedException: CWWIM0514W The 'dn' property is not defined.

For this error i found this information.

But i don't understand they want me do...

Description:

I have FederatedRepositories where only one LDAP repository.

UPDATE #2:

I made such TAI on WAS 8.5.5.2 and there no errors, just white screen. I tried auth user "bob" with group "wpsadmins". There are FederatedRepositories with one file-based built-in repository.

UPDATE #3:

I wrote custom application for WAS where i have a button, which make POST request to Servlet.

Partially code:

if (req.getRemoteUser() == null) {
    req
            .setAttribute("errorMessage",
                    "<b>Error: Please log in before accessing PrintUserInfo.<b>");
    RequestDispatcher disp = getServletContext().getRequestDispatcher(
            "/login.jsp");
    disp.forward(req, resp);
    return;
}
resp.setContentType("text/html");
PrintWriter out = new PrintWriter(resp.getOutputStream());

String id = WSSubject.getCallerPrincipal();
out.println("The WAS Subject layer thinks you are " + id);
    Context ic = new InitialContext();
    Object objRef = ic.lookup("UserRegistry");
    UserRegistry userReg = (UserRegistry) PortableRemoteObject.narrow(
            objRef, UserRegistry.class);
    out.println("<BR><BR>The user registry says your display name is: "
            + userReg.getUserDisplayName(req.getUserPrincipal()
                    .getName()));

    Subject subject = WSSubject.getCallerSubject();
    Set credSet = subject.getPublicCredentials(WSCredential.class);
    //should be impossible.
    if (credSet.size() > 1) {
        System.out
                .println("Expected only one WSCredential in Subject set");
        throw new Exception("Expected one WSCredential, found "
                + credSet.size());
    }
if (credSet.isEmpty()) {
    System.out.println("Credential set is empty");
    throw new Exception("Found no credentials");
}
//get one and only one element of Set
Iterator iter = credSet.iterator();
WSCredential creds = (WSCredential) iter.next();
out.println("<BR><BR>Looking into your Subject your userid is "
        + creds.getSecurityName());
out.println("<BR><BR>Looking into your Subject your uniqueid is "
        + creds.getUniqueSecurityName());
out
        .println("<BR><BR>Looking into your Subject I see these groups: ");
//List groups = helper.getGroups();
List groups = creds.getGroupIds();
iter = groups.iterator();
while (iter.hasNext()) {
    String gid = (String) iter.next();
    out.println("<BR>Group ID: " + gid);
}

New version of TAI:

String userid = "alisa";
String uniqueid = "bob";

// add admin group 

// stash in hashtable
Hashtable hashtable = new Hashtable();


try {
    InitialContext ctx = new InitialContext();
    UserRegistry reg  =(UserRegistry)ctx.lookup("UserRegistry");
    String wpsadminsGroupUniqueId = reg.getUniqueGroupId("wpsadmins");
    List<String> groups = new ArrayList<String>();
    groups.add(wpsadminsGroupUniqueId);
    hashtable.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groups);
} catch (Exception  e) {
    System.out.println("EXCEPTION IN TAI");
    e.printStackTrace();
}

hashtable.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID,uniqueid);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME,userid);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_CACHE_KEY,uniqueid+"MyCustom");

Subject subject = new Subject();
subject.getPublicCredentials().add(hashtable);
return TAIResult.create(HttpServletResponse.SC_OK, "ignored", subject);

So i got from Subject i get my credentials, includes userId, uniqueId and groups from LDAP.

Result:

The WAS Subject layer thinks you are alisa 

The user registry says your display name is: 

Looking into your Subject your userid is alisa 

Looking into your Subject your uniqueid is bob 

Looking into your Subject I see these groups: 
Group ID: group:domain:port/cn=wpsadmins,cn=CN,ou=OU,o=O,o=O,c=ru 

UPDATE #4

I added in TAI a few groups and than i authorize in Portal (i think), but i see only white screen without anything. What's wrong?

UPDATE #5

And WPS gives me an exception:

[26.03.15 18:47:41:006 AMT] 0000004e DefaultLoginF E com.ibm.wps.auth.impl.DefaultLoginFilter doLoginWithExceptions WpsException occured: com.ibm.wps.services.authentication.exceptions.UserRetrieveException: EJPSD0008E: Exception occurred while retrieving the user [null] from the user registry.
2

There are 2 answers

11
Gas On BEST ANSWER

You need to create full subject, for more details check Advanced authentication in WebSphere Application Server.

In short you need to use similar code:

String userid = "bob";//get from request
String uniqueid = "bob";

// stash in hashtable
Hashtable hashtable = new Hashtable();
hashtable.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID,uniqueid);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME,userid);
// hashtable.put(AttributeNameConstants.WSCREDENTIAL_GROUPS,groups);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_CACHE_KEY,uniqueid+"MyCustom");

Subject subject = new Subject();
subject.getPublicCredentials().add(hashtable);
return TAIResult.create(HttpServletResponse.SC_OK, "ignored", subject); 
0
Stefan Schmitt On

On the WPS Exception added in Update #5 WebSphere Portal requires the uniqueid to be a full qualified DN. In you case you only have a shortname. Portal does lookup the user at VMM using the DN and expects the WSCredential.getUniqueSecurityName() to return a DN.