10-23-2010 04:32 AM
Response remoteRes;
if (cachedNtlm)
{
Connector conn = connectorService.getConnector(this.endpoint, session);
ConnectorContext ctx = new ConnectorContext(null, getConnectionHeaders(conn));
remoteRes = conn.call("/touch", ctx, req, null);
}
else
{
Connector conn = connectorService.getConnector(this.endpoint, AuthenticationUtil.getUserId(req),
session);
ConnectorContext ctx = new ConnectorContext();
remoteRes = conn.call("/touch", ctx);
}
and I found the alfresco/service/touch 's description is:10-23-2010 08:15 AM
10-23-2010 10:59 PM
/touch is just a No-Op API used to verify and/or authenticate a SSO session. Share doesn't actually authenticate you (when using NTLM at least) - it delegates this job to the repository and the touch point is the way it does that since the configured filters of the repository will intercept the call and perform any SSO functionality on their part.It seems that I got it:
I guess there is no better reference for that than some lines of code below of what you posted. It hasn't been put into the wiki or a book since 99.9% of all users and developers never have to deal with this.
10-24-2010 09:34 AM
Response remoteRes = conn.call("/touch", ctx, req, null); //req contains the NTLM authentication header and its headers will be copied
// Check the authorization header
if (authHdr == null)
{
if (logger.isDebugEnabled())
logger.debug("New NTLM auth request from " + req.getRemoteHost() + " (" +
req.getRemoteAddr() + ":" + req.getRemotePort() + ")");
restartAuthProcess(session, res);
}
else
{
// Decode the received NTLM blob and validate
final byte[] authHdrByts = authHdr.substring(5).getBytes();
final byte[] ntlmByts = Base64.decode(authHdrByts);
int ntlmTyp = NTLMMessage.isNTLMType(ntlmByts);
if (ntlmTyp == NTLM.Type1)
{
// Process the type 1 NTLM message
Type1NTLMMessage type1Msg = new Type1NTLMMessage(ntlmByts);
// Start with a fresh session
session.invalidate();
session = req.getSession();
processType1(type1Msg, req, res, session);
}
else if (ntlmTyp == NTLM.Type3)
{
// Process the type 3 NTLM message
Type3NTLMMessage type3Msg = new Type3NTLMMessage(ntlmByts);
processType3(type3Msg, req, res, session, chain);
}
else
{
if (logger.isDebugEnabled())
logger.debug("NTLM not handled, redirecting to login page");
redirectToLoginPage(req, res);
}
}
10-24-2010 10:03 AM
if(request.getURI().contains("mylogin"))
{
Session.Invalidate();
RedirectToLoginPage();
return;
}
with the code above, I then can type http://localhost:8080/share/page/mylogin to browse to the login page of share.10-24-2010 10:58 AM
private void restartAuthProcess(HttpSession session, HttpServletRequest req, HttpServletResponse res) throws IOException
{
// Clear any cached logon details from the sessiom
session.invalidate();
// restart the authentication process for NTLM
res.setHeader(HEADER_WWWAUTHENTICATE, AUTH_NTLM);
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
res.setContentType("text/html; charset=utf-8");
final PrintWriter out = res.getWriter();
out.println("<html><head>");
out.println("<meta http-equiv=\"Refresh\" content=\"0; url=" +
req.getContextPath() + "/page?f=default&pt=login" +
"\">");
out.println("</head><body><p>Please <a href=\"" +
req.getContextPath() + "/page?f=default&pt=login" +
"\">log in</a>.</p>");
out.println("</body></html>");
out.close();
res.flushBuffer();
}
Index: projects/web-client/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java
===================================================================
— projects/web-client/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java (revision 23221)
+++ projects/web-client/source/java/org/alfresco/web/app/servlet/NTLMAuthenticationFilter.java (working copy)
@@ -83,7 +83,8 @@
}
// Use the web client user attribute name
- setUserAttributeName(AuthenticationHelper.AUTHENTICATION_USER);
+ setUserAttributeName(AuthenticationHelper.AUTHENTICATION_USER);
+ setTicketLogons(true);
}
Index: projects/web-client/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java
===================================================================
— projects/web-client/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java (revision 23221)
+++ projects/web-client/source/java/org/alfresco/web/app/servlet/KerberosAuthenticationFilter.java (working copy)
@@ -87,6 +87,7 @@
// Use the web client user attribute name
setUserAttributeName(AuthenticationHelper.AUTHENTICATION_USER);
+ setTicketLogons(true);
}
Index: projects/remote-api/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java
===================================================================
— projects/remote-api/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java (revision 23221)
+++ projects/remote-api/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java (working copy)
@@ -222,6 +222,10 @@
boolean ticketValid = false;
String ticket = req.getParameter(ARG_TICKET);
+ if(ticket == null){
+ //failover for alf_ticket
+ ticket = req.getParameter("alf_ticket");
+ }
if (ticket != null && ticket.length() != 0)
{
public boolean isAuthenticated(String endpoint,
ConnectorSession connectorSession) {
final boolean ticketAuthentication = super.isAuthenticated(endpoint,
connectorSession);
final HttpSession session = SessionTrackerFilter.getCurrentSession();
final boolean externalAuthentication = session != null
&& Boolean.TRUE
.equals(session
.getAttribute(UserFactory.SESSION_ATTRIBUTE_EXTERNAL_AUTH));
final boolean result = ticketAuthentication || externalAuthentication;
return result;
}
10-24-2010 11:30 PM
1) Login - username problem: I do not have a concrete idea what might be the problem with IE/FF differences there, but I do remember I too had some problems in that general area when I backported some Kerberos bugfixes to an older Alfresco/Share version and also switched from SSO/login-only to SSO/login-mixed.So do you remember how do you fix this problem then ?
try
{
// check whether there is already a user logged in
HttpSession session = request.getSession(false);
if (session != null && request.getSession().getAttribute(UserFactory.SESSION_ATTRIBUTE_KEY_USER_ID) != null)
{
// log out the current user
AuthenticationUtil.logout(request, response);
}
UserFactory userFactory = FrameworkUtil.getServiceRegistry().getUserFactory();
// see if we can authenticate the user
boolean authenticated = userFactory.authenticate(request, username, password);
if (authenticated)
{
// this will fully reset all connector sessions
RequestContext context = FrameworkUtil.getCurrentRequestContext();
AuthenticationUtil.login(request, response, username);
// mark the fact that we succeeded
success = true;
}
}
share call the SlingshotUserFactory directly to authenticate the user, and I think CredentialsVault will keep this authentication into session. And this is what happens when using login form.11-14-2010 04:13 PM
11-30-2010 09:58 PM
I am sorry I didn't get back to you sooner - it was quite a busy time at work and somehow the email notification about your reply got lost between all the other emails…
1) As far as I can remember, the problems I had in that direction disappeared after I implemented my own authenticator for Share that prevents unnecessary authentication request when the user has been authenticated via SSO. The base problem for me was that in a SSO scenario, the default authenticator of Share did not know of the SSO and was trying to login my user although it did not know of a password. The login request submitted contained a username but no password (null reference), causing users to accidentally have their domain account locked after 3 attempts to log them in this way.
2) The reason why you need the authenticator is outlined in 1). Whenever a remote connector is tasked to make a call to the repository, it first asks the authenticator if the current user has already been authenticated. If not, it initiates a login handshake. The default authenticator does not know of SSO authentication and thus ALWAYS starts a login handshake (even if it does not know the password). The isAuthenticated method is defined in the interface Authenticator.
3) The filter that authenticates the request made to "/wcs/touch" does not use username and password directly to authenticate the user. The request made by the client contains a special header with a so-called NTLM Token. This token gets passed to "/wcs/touch" and the filter uses that token to authenticate the user. The token contains both the user name and a hashed version of the password (the cleartext password cannot be read from this). Depending on wether you are using alfrescoNtlm or passthru, the filter compares the hashed password with the one stored in the database or delegates the token to the domain controller of your network (which then checks the users hashed password). There is no such thing as an AlfrescoUserFactory on the repository side - here, the AuthenticationService (or more precisely an implementation of this interface) is used.
12-01-2010 04:25 AM
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.