use of org.forgerock.openam.radius.common.UserNameAttribute 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 org.forgerock.openam.radius.common.UserNameAttribute in project OpenAM by OpenRock.
the class RadiusConn method authenticate.
/**
* Authenticates the username and password against the remote servers.
*
* @param name the username.
* @param password the password.
* @throws IOException if there is a problem.
* @throws NoSuchAlgorithmException if there is a problem.
* @throws RejectException if there is a problem.
* @throws ChallengeException if there is a problem.
*/
public void authenticate(String name, String password) throws IOException, NoSuchAlgorithmException, RejectException, ChallengeException {
AccessRequest req = createAccessRequest();
req.addAttribute(new UserNameAttribute(name));
req.addAttribute(new UserPasswordAttribute(req.getAuthenticator(), secret, password));
req.addAttribute(new NASIPAddressAttribute(InetAddress.getLocalHost()));
req.addAttribute(new NASPortAttribute(socket.getLocalPort()));
sendPacket(req);
}
use of org.forgerock.openam.radius.common.UserNameAttribute in project OpenAM by OpenRock.
the class RadiusConn method replyChallenge.
/**
* Sends an access-request to the server in response to a challenge request.
*
* @param name the username.
* @param password the password.
* @param ce the challenge exception providing access to the original challenge response.
* @throws IOException if there is a problem.
* @throws NoSuchAlgorithmException if there is a problem.
* @throws RejectException if there is a problem.
* @throws ChallengeException if there is a problem.
*/
public void replyChallenge(String name, String password, ChallengeException ce) throws IOException, NoSuchAlgorithmException, RejectException, ChallengeException {
StateAttribute state = (StateAttribute) ce.getAttributeSet().getAttributeByType(AttributeType.STATE);
if (state == null) {
throw new IOException("State not found in challenge");
}
AccessRequest req = createAccessRequest();
// needed in challenge
req.addAttribute(state);
if (name != null) {
req.addAttribute(new UserNameAttribute(name));
}
req.addAttribute(new UserPasswordAttribute(req.getAuthenticator(), secret, password));
req.addAttribute(new NASIPAddressAttribute(InetAddress.getLocalHost()));
req.addAttribute(new NASPortAttribute(socket.getLocalPort()));
sendPacket(req);
}
use of org.forgerock.openam.radius.common.UserNameAttribute in project OpenAM by OpenRock.
the class OpenAMAuthHandler method handle.
/**
* Handles the request in potentially two distinct ways depending on whether a state attribute is found in the
* request or not. When no state field is found this is an initial request starting the authentication process and
* the request will have username and password embedded and ready for consumption by the first module in the chain.
* Any request with a state attribute is a user response to a previous challenge response that we sent back to them
* in a previously started authentication process. The number of challenge responses that are sent and their
* corresponding replies is dependent upon the number of modules in the chain and the number of callback fields in
* each set of callbacks. A set of callbacks represents one grouping of data needed by a module to complete its next
* step in the authentication process that it implements. This grouping in a web environment constitutes a single
* page into which a number of fields can receive data. However, to gather additional feedback from a user the
* radius protocol only supports a challenge response with a text message and state and radius clients typically
* present that message and a single text input field with a label like, "Answer", and submit and cancel buttons.
* This means that we only get a single answer per radius challenge response. Therefore, for some callback groupings
* we will need to return multiple challenge responses before we can submit the callback set's user response values
* back to the module to take the next step in authentication.
*
* @param request
* the access request
* @param response
* - the response to be sent to the client.
* @param context
* - provides methods that the handler can use to obtain information about the context in which the
* request was made, for example the name and IP address of the client from which the request was
* received.
* @return
* @throws RadiusProcessingException
* - when the response can not be sent.
*/
@Override
public void handle(RadiusRequest request, RadiusResponse response, RadiusRequestContext context) throws RadiusProcessingException {
LOG.message("Entering OpenAMAuthHandler.handle");
response.setRealm(realm);
final StateAttribute state = (StateAttribute) request.getAttribute(StateAttribute.class);
ContextHolder holder = null;
if (state != null) {
final String cacheKey = state.getState();
holder = contextCache.get(cacheKey);
}
// always get password attribute regardless of whether starting or returning more input since user input is
// always sent via the password field.
final UserPasswordAttribute credAtt = (UserPasswordAttribute) request.getAttribute(UserPasswordAttribute.class);
String credential = null;
try {
credential = credAtt.extractPassword(context.getRequestAuthenticator(), context.getClientSecret());
} catch (final IOException e) {
LOG.error("Unable to extract credential field from RADIUS request. Denying Access.", e);
rejectAccessAndTerminateProcess(response, holder);
LOG.message("Leaving OpenAMAuthHandler.handle();");
return;
}
if (holder == null) {
holder = this.contextCache.createCachedContextHolder();
request.setContextHolderKey(holder.getCacheKey());
eventBus.post(new AuthRequestReceivedEvent(request, response, context));
final UserNameAttribute usrAtt = (UserNameAttribute) request.getAttribute(UserNameAttribute.class);
holder = startAuthProcess(holder, response, usrAtt, credential);
if (holder == null || holder.getAuthPhase() == ContextHolder.AuthPhase.TERMINATED) {
// oops. something happened and reject message was already sent. so drop out here.
LOG.message("Leaving OpenAMAuthHandler.handle(); Auth phase is TERMINATED.");
return;
}
} else {
request.setContextHolderKey(holder.getCacheKey());
eventBus.post(new AuthRequestReceivedEvent(request, response, context));
}
gatherUserInput(response, holder, credential, state);
if (holder.getAuthPhase() == ContextHolder.AuthPhase.FINALIZING) {
finalizeAuthProcess(response, holder);
}
LOG.message("Leaving OpenAMAuthHandler.handle();");
return;
}
use of org.forgerock.openam.radius.common.UserNameAttribute in project OpenAM by OpenRock.
the class ConsoleClient method run.
/**
* Calls the server in a thread.
*/
@Override
public void run() {
try {
final DatagramChannel chan = DatagramChannel.open();
// request id
short reqId = 1;
final SecureRandom random = new SecureRandom();
final InetSocketAddress serverAddr = new InetSocketAddress(this.host, this.port);
final NASIPAddressAttribute nasAddr = new NASIPAddressAttribute(InetAddress.getLocalHost());
final NASPortAttribute nasPort = new NASPortAttribute(chan.socket().getLocalPort());
StateAttribute state = null;
// String username = "boydmr"; // TODO: restore
final String username = getUserInputFor("Username", null);
// String passwordOrAnswer = "password"; // TODO: restore
String passwordOrAnswer = getUserInputFor("Password", null);
System.out.println();
boolean finished = false;
// ready for writing
final ByteBuffer bufIn = ByteBuffer.allocate(4096);
while (!finished) {
final RequestAuthenticator reqAuthR = new RequestAuthenticator(random, this.secret);
final AccessRequest req = new AccessRequest(reqId++, reqAuthR);
req.addAttribute(new UserNameAttribute(username));
req.addAttribute(new UserPasswordAttribute(req.getAuthenticator(), this.secret, passwordOrAnswer));
req.addAttribute(nasAddr);
req.addAttribute(nasPort);
if (state != null) {
req.addAttribute(state);
}
final ByteBuffer reqBuf = ByteBuffer.wrap(req.getOctets());
if (logTraffic) {
System.out.println("Packet To " + host + ":" + port);
System.out.println(RadiusRequestContext.getPacketRepresentation(req));
}
chan.send(reqBuf, serverAddr);
// now handle responses possibly sending additional requests
chan.receive(bufIn);
// prepare buffer for reading out
bufIn.flip();
final Packet res = PacketFactory.toPacket(bufIn);
// prepare buffer for next response
bufIn.clear();
if (logTraffic) {
System.out.println("Packet From " + host + ":" + port);
System.out.println(RadiusRequestContext.getPacketRepresentation(res));
}
if (res instanceof AccessReject) {
System.out.println("---> Sorry. Not Authenticated.");
System.out.println();
finished = true;
} else if (res instanceof AccessAccept) {
System.out.println("---> SUCCESS! You've Authenticated!");
System.out.println();
finished = true;
} else if (res instanceof AccessChallenge) {
final AccessChallenge chng = (AccessChallenge) res;
state = (StateAttribute) getAttribute(StateAttribute.class, res);
final ReplyMessageAttribute msg = (ReplyMessageAttribute) getAttribute(ReplyMessageAttribute.class, res);
String message = null;
if (msg != null) {
message = msg.getMessage();
}
passwordOrAnswer = getUserInputFor("Answer", message);
System.out.println();
}
}
} catch (final Exception e) {
e.printStackTrace();
}
}
Aggregations