I have a use case where my own site (A) consolidates data from other sites.
When a user logs into site A, those credentials are used to login to the
other sites. A user might have access to all or none of the other sites.
I launch threads to login to the other sites. When I wait on all the
threads to complete, everything works as expected. To speed up the login, I
want the login to return when the first successful login completes.
However, when I do this, there seems to be a race condition where not all of
the successful principals are added. Sometimes I get access to all the
sites, sometimes only a partial list.
*The real question is can principals be added to the AuthenticationInfo
object after it is returned from doGetAuthenticationInfo()?*
This is my doGetAuthenticationInfo code in my realm:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws
AuthenticationException {
List<String> urls = getUrls();
UsernamePasswordToken usernamePasswordToken =
(UsernamePasswordToken)token;
MyAuthenticationInfo authInfo = new
MyAuthenticationInfo(token.getCredentials(),
this.getName());
ArrayList<LoginTask> threads = new ArrayList<LoginTask>();
for (String url: urls) {
LoginTask t = new LoginTask(url, usernamePasswordToken,
authInfo);
t.start();
threads.add(t);
}
boolean successful = false;
int threadsComplete = 0;
while (!successful && threadsComplete < threads.size() - 1) {
threadsComplete = 0;
for (LoginTask t : threads) {
if (!t.isAlive()) {
threadsComplete++;
if (t.getPrincipal() != null) {
successful = true;
break;
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
return authInfo;
}
The login thread calls this:
public void run() {
try {
String username = m_usernamePasswordToken.getUsername();
String password = new
String(m_usernamePasswordToken.getPassword());
Subject s = SecurityUtils.getSubject();
String sessionId = s.getSession().getId().toString();
doLogin(m_url, username, password, sessionId);
//throws exception if
login fails
m_principal = new
MyPrincipal(m_usernamePasswordToken.getPrincipal().toString(), sessionId,
m_url.toLowerCase());
m_authInfo.addPrincipal(m_principal);
} catch (Exception e) {
} finally {
ThreadContext.unbindSubject();
ThreadContext.remove();
}
}
I'm guessing the problem is once the main thread in
doGetAuthenticationInfo() is returned, I can't add more principals to that
AuthenticationInfo object. But why? Is there a way around this?
--
View this message in context:
http://shiro-user.582556.n2.nabble.com/Add-principals-to-AuthenticationInfo-object-after-doGetAuthenticationInfo-returns-tp7581395.html
Sent from the Shiro User mailing list archive at Nabble.com.