use of javax.security.auth.callback.NameCallback in project OpenAM by OpenRock.
the class OpenAMAuthHandler method startAuthProcess.
/**
* Starts the authentication process by creating a new AuthContextLocale and the submitted username and password and
* passing those to the first module in the authentication chain and completing authentication if that is the only
* module in the chain or crafting a suitable challenge response to start gathering values for the next module's
* callbacks. Returns true if authentication was started and user requirements beyond username and password can now
* be solicited or false if starting failed and a reject message has already been generated.
*
* @param response
* the response object for the radius request
* @param reqAttsMap
* @param credential
*/
private ContextHolder startAuthProcess(ContextHolder holder, RadiusResponse response, UserNameAttribute usrAtt, String credential) {
LOG.message("Entering OpenAMAuthHandler.startAuthProcess");
// now create an authContext and trigger loading of whatever authN modules will be used
try {
holder.setAuthContext(amAuthFactory.getAuthContext(realm));
} catch (final AuthLoginException e) {
LOG.error("Unable to start create " + AuthContext.class.getName() + ". Denying Access.", e);
rejectAccessAndTerminateProcess(response, holder);
LOG.message("Leaving OpenAMAuthHandler.startAuthProcess");
return holder;
}
try {
holder.getAuthContext().login(AuthContext.IndexType.SERVICE, authChain);
} catch (final AuthLoginException e) {
LOG.error("Unable to start login process. Denying Access.", e);
rejectAccessAndTerminateProcess(response, holder);
LOG.message("Leaving OpenAMAuthHandler.startAuthProcess");
return holder;
}
if (!isNextCallbackSetAvailable(response, holder)) {
// since we must have callbacks when starting up the authn process to handle username and password.
if (holder.getAuthPhase() != ContextHolder.AuthPhase.TERMINATED) {
LOG.error("Unable to start login process. No callbacks available. Denying Access.");
rejectAccessAndTerminateProcess(response, holder);
}
LOG.message("Leaving OpenAMAuthHandler.startAuthProcess");
return holder;
}
// for RADIUS we have username and password within the initial request. Therefore, the first module in the
// chain must support a name and password callback. so walk the set of callbacks representing the first
// module and inject and then test for further module requirements. if any exist then we must craft a
// suitable challenge response and await the next request that gets submitted after the radius client has
// gathered those values.
boolean injectedUsr = false;
boolean injectedPwd = false;
final Callback[] callbacks = holder.getCallbacks();
for (int i = holder.getIdxOfCurrentCallback(); i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
holder.incrementIdxOfCurrentCallback();
final NameCallback nm = (NameCallback) callbacks[i];
nm.setName(usrAtt.getName());
injectedUsr = true;
} else if (callbacks[i] instanceof PasswordCallback) {
holder.incrementIdxOfCurrentCallback();
final PasswordCallback pc = (PasswordCallback) callbacks[i];
pc.setPassword(credential.toCharArray());
injectedPwd = true;
} else {
holder.incrementIdxOfCurrentCallback();
}
}
// did we have NameCallback and PasswordCallback to inject the username and password?
if (injectedUsr && injectedPwd) {
holder.getAuthContext().submitRequirements(callbacks);
// cLog.warning("--- submitting usr/pwd in startAuthProcess, set callbacks=null");
// triggers loading of next set, conveys to gatherer that we have just started
holder.setCallbacks(null);
} else {
// if we get here and didn't submit, then the callbacks array representing the requirements of the first
// module in the chain didn't support username and password. So log the error and reject access.
final String msg = "First callback set for first module" + (holder.getModuleName() != null ? " '" + holder.getModuleName() + "'" : "") + " in authentication chain '" + this.authChain + "' does not support Username and Password callbacks. Denying Access.";
LOG.error(msg);
rejectAccessAndTerminateProcess(response, holder);
}
// if we get here then we successfully started the authN process
holder.setAuthPhase(ContextHolder.AuthPhase.GATHERING_INPUT);
LOG.message("Leaving OpenAMAuthHandler.startAuthProcess");
return holder;
}
use of javax.security.auth.callback.NameCallback in project OpenAM by OpenRock.
the class OpenAMAuthHandler method injectAnswerForCallback.
/**
* Injects the user's answer into the callback currently waiting for one with proper handling for the type of
* callback. Increments the index of the current callback and returns true if the value was successly injected or
* false if it failed and terminated authentication.
*
* @param respHandler
* @param holder
* @param answer
*/
private boolean injectAnswerForCallback(RadiusResponse response, ContextHolder holder, String answer) {
final Callback[] callbacks = holder.getCallbacks();
if (callbacks == null) {
return false;
}
final Callback cb = callbacks[holder.getIdxOfCurrentCallback()];
// so that we are sitting on that callback in the next call
holder.incrementIdxOfCurrentCallback();
if (cb instanceof NameCallback) {
final NameCallback nc = (NameCallback) cb;
((NameCallback) cb).setName(answer);
// cLog.warning("--- set NameCallback=" + answer);
} else if (cb instanceof PasswordCallback) {
final PasswordCallback pc = (PasswordCallback) cb;
pc.setPassword(answer.toCharArray());
// cLog.warning("--- set PasswordCallback=" + answer);
} else if (cb instanceof ChoiceCallback) {
final ChoiceCallback cc = (ChoiceCallback) cb;
final int maxIdx = cc.getChoices().length - 1;
if ("".equals(answer)) {
// user didn't provide an answer so accept default
cc.setSelectedIndex(cc.getDefaultChoice());
// cLog.warning("--- set ChoiceCallback=default(" + cc.getDefaultChoice() + ")");
return true;
}
final boolean answerContainsSeparator = answer.indexOf(' ') != -1;
if (cc.allowMultipleSelections() && answerContainsSeparator) {
// may need to parse answer
if (answerContainsSeparator) {
final String[] answers = answer.split(" ");
final List<Integer> idxs = new ArrayList<Integer>();
for (final String ans : answers) {
if (!"".equals(ans)) {
final int idx = parseInt(response, ans, answer, maxIdx, holder, cb);
if (idx == -1) {
// cLog.warning("--- ChoiceCallback failed parsing mult");
return false;
}
idxs.add(idx);
}
}
final int[] selected = new int[idxs.size()];
for (int i = 0; i < selected.length; i++) {
selected[i] = idxs.get(i);
}
cc.setSelectedIndexes(selected);
// cLog.warning("--- set ChoiceCallback=" + Arrays.asList(selected));
}
} else {
final int idx = parseInt(response, answer, answer, maxIdx, holder, cb);
if (idx == -1) {
// cLog.warning("--- ChoiceCallback failed parsing");
return false;
}
cc.setSelectedIndex(idx);
// cLog.warning("--- set ChoiceCallback=" + idx);
}
} else if (cb instanceof ConfirmationCallback) {
final ConfirmationCallback cc = (ConfirmationCallback) cb;
final int maxIdx = cc.getOptions().length - 1;
if ("".equals(answer)) {
// user didn't provide an answer so accept default
cc.setSelectedIndex(cc.getDefaultOption());
// cLog.warning("--- set ConfirmationCallback=default(" + cc.getDefaultOption() + ")");
return true;
}
final int idx = parseInt(response, answer, answer, maxIdx, holder, cb);
if (idx == -1) {
// cLog.warning("--- ConfirmationCallback failed parsing");
return false;
}
cc.setSelectedIndex(idx);
// cLog.warning("--- set ConfirmationCallback=" + idx);
} else {
LOG.error("Unrecognized callback type '" + cb.getClass().getSimpleName() + "' while processing challenge response. Unable to submit answer. Denying Access.");
rejectAccessAndTerminateProcess(response, holder);
return false;
}
// reset the timeout since we just received confirmation that the user is still there.
holder.setMillisExpiryPoint(System.currentTimeMillis() + holder.getMillisExpiryForCurrentCallbacks());
return true;
}
use of javax.security.auth.callback.NameCallback in project OpenAM by OpenRock.
the class OpenAMAuthHandlerTest method handle.
/**
* Test the following method;.
*
* @see org.forgerock.openam.radius.server.spi.handlers.OpenAMAuthHandler#handle
* @throws RadiusProcessingException - should not happen.
* @throws AuthLoginException - should not happen.
* @throws IOException - should not happen.
*/
@Test(enabled = true)
public void handle() throws RadiusProcessingException, AuthLoginException, IOException {
// given
final Callback pagePropCallback = new PagePropertiesCallback("test_module", null, null, 0, null, false, null);
final Callback nameCallback = new NameCallback("Username:");
final Callback pwCallback = new PasswordCallback("pw_prompt", false);
final Callback[] callbacks = new Callback[] { pagePropCallback, nameCallback, pwCallback };
final String testRealm = "test_realm";
final String testChain = "test_chain";
final String cacheKey = "cache_key";
final Properties props = new Properties();
props.setProperty("realm", testRealm);
props.setProperty("chain", testChain);
final Status status = mock(Status.class);
final AuthContext authContext = mock(AuthContext.class);
when(authContext.getStatus()).thenReturn(AuthContext.Status.SUCCESS);
when(status.toString()).thenReturn("success");
when(authContext.hasMoreRequirements()).thenReturn(true, false);
when(authContext.getRequirements(true)).thenReturn(callbacks);
// Context and context holder
final ContextHolder holder = mock(ContextHolder.class);
final OpenAMAuthFactory ctxHolderFactory = mock(OpenAMAuthFactory.class);
when(holder.getCacheKey()).thenReturn(cacheKey);
when(holder.getAuthContext()).thenReturn(authContext);
when(holder.getAuthPhase()).thenReturn(AuthPhase.STARTING, AuthPhase.GATHERING_INPUT, AuthPhase.FINALIZING);
when(holder.getCallbacks()).thenReturn(callbacks, callbacks, (Callback[]) null);
when(holder.getIdxOfCurrentCallback()).thenReturn(1, 2);
final ContextHolderCache ctxHolderCache = mock(ContextHolderCache.class);
when(ctxHolderCache.createCachedContextHolder()).thenReturn(holder);
when(ctxHolderCache.get(isA(String.class))).thenReturn(holder);
EventBus eventBus = new EventBus();
final OpenAMAuthHandler handler = new OpenAMAuthHandler(ctxHolderFactory, ctxHolderCache, eventBus);
handler.init(props);
final Authenticator authenticator = mock(Authenticator.class);
when(authenticator.getOctets()).thenReturn("authenticator".getBytes());
// final StateAttribute mockStateAttribute = new StateAttribute("1");
final UserPasswordAttribute mockUserPasswordAttribute = new UserPasswordAttribute(authenticator, "secret", "testPassword");
final UserNameAttribute mockUsernameAttribute = new UserNameAttribute("testUser");
final AttributeSet mockAttrSet = mock(AttributeSet.class);
when(mockAttrSet.size()).thenReturn(2);
// when(mockAttrSet.getAttributeAt(0)).thenReturn(mockStateAttribute);
when(mockAttrSet.getAttributeAt(0)).thenReturn(mockUserPasswordAttribute);
when(mockAttrSet.getAttributeAt(1)).thenReturn(mockUsernameAttribute);
final AccessRequest mockRequestPacket = mock(AccessRequest.class);
when(mockRequestPacket.getAttributeSet()).thenReturn(mockAttrSet);
RadiusRequestContext reqCtx = mock(RadiusRequestContext.class);
when(reqCtx.getRequestAuthenticator()).thenReturn((mock(Authenticator.class)));
when(reqCtx.getClientSecret()).thenReturn("victoria");
RadiusResponse response = new RadiusResponse();
Packet mockPacket = mock(Packet.class);
when(mockPacket.getIdentifier()).thenReturn((short) 1);
RadiusRequest request = mock(RadiusRequest.class);
when(request.getRequestPacket()).thenReturn(mockPacket);
UserNameAttribute userName = mock(UserNameAttribute.class);
when(userName.getName()).thenReturn("Fred");
UserPasswordAttribute userPassword = mock(UserPasswordAttribute.class);
when(userPassword.extractPassword(isA(Authenticator.class), isA(String.class))).thenReturn("password");
when(request.getAttribute(UserPasswordAttribute.class)).thenReturn(userPassword);
when(request.getAttribute(UserNameAttribute.class)).thenReturn(userName);
String password = userPassword.extractPassword(reqCtx.getRequestAuthenticator(), reqCtx.getClientSecret());
assertThat(password).isNotNull();
// when
handler.handle(request, response, reqCtx);
// then
verify(authContext, times(1)).login(AuthContext.IndexType.SERVICE, testChain);
verify(ctxHolderFactory, times(1)).getAuthContext(testRealm);
verify(holder, times(3)).getCallbacks();
verify(holder, times(1)).setAuthPhase(ContextHolder.AuthPhase.TERMINATED);
verify(authContext, times(1)).logout();
}
use of javax.security.auth.callback.NameCallback in project OpenAM by OpenRock.
the class SpecialRepo method authenticate.
public boolean authenticate(Callback[] credentials) throws IdRepoException, AuthLoginException {
debug.message("SpecialRepo:authenticate called");
// Obtain user name and password from credentials and authenticate
String username = null;
String password = null;
for (int i = 0; i < credentials.length; i++) {
if (credentials[i] instanceof NameCallback) {
username = ((NameCallback) credentials[i]).getName();
if (debug.messageEnabled()) {
debug.message("SpecialRepo:authenticate username: " + username);
}
} else if (credentials[i] instanceof PasswordCallback) {
char[] passwd = ((PasswordCallback) credentials[i]).getPassword();
if (passwd != null) {
password = new String(passwd);
debug.message("SpecialRepo:authN passwd present");
}
}
}
if (username == null || password == null) {
return (false);
}
Map sharedState = new HashMap();
sharedState.put(ISAuthConstants.SHARED_STATE_USERNAME, username);
sharedState.put(ISAuthConstants.SHARED_STATE_PASSWORD, password);
debug.message("SpecialRepo:authenticate inst. SMSAuthModule");
SMSAuthModule module = new SMSAuthModule();
debug.message("SpecialRepo:authenticate SMSAuthModule:init");
module.initialize(new AuthSubject(), null, sharedState, Collections.EMPTY_MAP);
boolean answer = false;
try {
answer = module.login();
if (debug.messageEnabled()) {
debug.message("SpecialRepo:authenticate login: " + answer);
}
} catch (LoginException le) {
if (debug.warningEnabled()) {
debug.warning("authentication: login exception", le);
}
if (le instanceof AuthLoginException) {
throw ((AuthLoginException) le);
}
}
return (answer);
}
use of javax.security.auth.callback.NameCallback in project OpenAM by OpenRock.
the class AgentsRepo method authenticate.
public boolean authenticate(Callback[] credentials) throws IdRepoException, AuthLoginException {
if (debug.messageEnabled()) {
debug.message("AgentsRepo.authenticate() called");
}
// Obtain user name and password from credentials and compare
// with the ones from the agent profile to authorize the agent.
String username = null;
String unhashedPassword = null;
String password = null;
for (int i = 0; i < credentials.length; i++) {
if (credentials[i] instanceof NameCallback) {
username = ((NameCallback) credentials[i]).getName();
if (debug.messageEnabled()) {
debug.message("AgentsRepo.authenticate() username: " + username);
}
} else if (credentials[i] instanceof PasswordCallback) {
char[] passwd = ((PasswordCallback) credentials[i]).getPassword();
if (passwd != null) {
unhashedPassword = new String(passwd);
password = hashAlgStr + Hash.hash(unhashedPassword);
if (debug.messageEnabled()) {
debug.message("AgentsRepo.authenticate() passwd " + "present");
}
}
}
}
if (username == null || (username.length() == 0) || password == null || unhashedPassword == null) {
Object[] args = { NAME };
throw new IdRepoException(IdRepoBundle.BUNDLE_NAME, IdRepoErrorCode.UNABLE_TO_AUTHENTICATE, args);
}
SSOToken adminToken = (SSOToken) AccessController.doPrivileged(AdminTokenAction.getInstance());
boolean answer = false;
String userid = username;
try {
/* Only agents with IdType.AGENTONLY is used for authentication,
* not the agents with IdType.AGENTGROUP.
* AGENTGROUP is for storing common properties.
*/
if (LDAPUtils.isDN(username)) {
userid = LDAPUtils.rdnValueFromDn(username);
}
Set pSet = new HashSet(2);
pSet.add("userpassword");
pSet.add(oauth2Attribute);
Map ansMap = new HashMap();
String userPwd = null;
ansMap = getAttributes(adminToken, IdType.AGENT, userid, pSet);
Set userPwdSet = (Set) ansMap.get("userpassword");
if ((userPwdSet != null) && (!userPwdSet.isEmpty())) {
userPwd = (String) userPwdSet.iterator().next();
if (!(answer = password.equals(userPwd)) && !(answer = oauth2PasswordMatch(ansMap, unhashedPassword, userPwd))) {
throw (new InvalidPasswordException("invalid password", userid));
}
}
if (debug.messageEnabled()) {
debug.message("AgentsRepo.authenticate() result: " + answer);
}
} catch (SSOException ssoe) {
if (debug.warningEnabled()) {
debug.warning("AgentsRepo.authenticate(): " + "Unable to authenticate SSOException: " + ssoe.getMessage());
}
}
return (answer);
}
Aggregations