@Test public void grantAccessTokenUserNotFound() throws Exception { oauth.clientId("resource-owner"); OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("secret", "invalid", "invalid"); assertEquals(401, response.getStatusCode()); assertEquals("invalid_grant", response.getError()); events .expectLogin() .client("resource-owner") .user((String) null) .session((String) null) .detail(Details.AUTH_METHOD, "oauth_credentials") .detail(Details.RESPONSE_TYPE, "token") .detail(Details.USERNAME, "invalid") .removeDetail(Details.CODE_ID) .removeDetail(Details.REDIRECT_URI) .removeDetail(Details.CONSENT) .error(Errors.INVALID_USER_CREDENTIALS) .assertEvent(); }
private void loginSuccessAndLogout(String username, String password) { loginPage.open(); loginPage.login(username, password); Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE)); oauth.openLogout(); }
@Test public void authorizationRequestNoState() throws IOException { AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password"); Assert.assertTrue(response.isRedirected()); Assert.assertNotNull(response.getCode()); Assert.assertNull(response.getState()); Assert.assertNull(response.getError()); oauth.verifyCode(response.getCode()); }
@Test public void authorizationRequestInstalledApp() throws IOException { oauth.redirectUri(Constants.INSTALLED_APP_URN); oauth.doLogin("test-user@localhost", "password"); String title = driver.getTitle(); Assert.assertTrue(title.startsWith("Success code=")); String code = driver.findElement(By.id(OAuth2Constants.CODE)).getText(); oauth.verifyCode(code); }
@Test public void changeClientIdTest() throws Exception { keycloakRule.update( new KeycloakRule.KeycloakSetup() { @Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { ClientModel app = appRealm.getClientByClientId("service-account-cl"); app.setClientId("updated-client"); } }); oauth.clientId("updated-client"); OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret1"); assertEquals(200, response.getStatusCode()); AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken()); Assert.assertEquals( "updated-client", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID)); // Username still same. Client ID changed events .expectClientLogin() .client("updated-client") .user(userId) .session(accessToken.getSessionState()) .detail(Details.TOKEN_ID, accessToken.getId()) .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) .detail( Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "service-account-cl") .assertEvent(); // Revert change keycloakRule.update( new KeycloakRule.KeycloakSetup() { @Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { ClientModel app = appRealm.getClientByClientId("updated-client"); app.setClientId("service-account-cl"); } }); }
@Test public void grantAccessTokenMissingGrantType() throws Exception { oauth.clientId("resource-owner"); DefaultHttpClient client = new DefaultHttpClient(); try { HttpPost post = new HttpPost(oauth.getResourceOwnerPasswordCredentialGrantUrl()); OAuthClient.AccessTokenResponse response = new OAuthClient.AccessTokenResponse(client.execute(post)); assertEquals(400, response.getStatusCode()); assertEquals("invalid_request", response.getError()); assertEquals("Missing form parameter: grant_type", response.getErrorDescription()); } finally { client.close(); } }
@Test public void sessions() { loginPage.open(); loginPage.clickRegister(); registerPage.register( "view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password"); Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent(); String userId = registerEvent.getUserId(); events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent(); sessionsPage.open(); Assert.assertTrue(sessionsPage.isCurrent()); List<List<String>> sessions = sessionsPage.getSessions(); Assert.assertEquals(1, sessions.size()); Assert.assertEquals("127.0.0.1", sessions.get(0).get(0)); // Create second session WebDriver driver2 = WebRule.createWebDriver(); try { OAuthClient oauth2 = new OAuthClient(driver2); oauth2.state("mystate"); oauth2.doLogin("view-sessions", "password"); Event login2Event = events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent(); sessionsPage.open(); sessions = sessionsPage.getSessions(); Assert.assertEquals(2, sessions.size()); sessionsPage.logoutAll(); events.expectLogout(registerEvent.getSessionId()); events.expectLogout(login2Event.getSessionId()); } finally { driver2.close(); } }
@Test public void grantAccessTokenInvalidClientCredentials() throws Exception { oauth.clientId("resource-owner"); OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("invalid", "test-user@localhost", "password"); assertEquals(400, response.getStatusCode()); assertEquals("unauthorized_client", response.getError()); events .expectLogin() .client("resource-owner") .session((String) null) .clearDetails() .error(Errors.INVALID_CLIENT_CREDENTIALS) .user((String) null) .assertEvent(); }
@Test public void clientCredentialsInvalidClientCredentials() throws Exception { oauth.clientId("service-account-cl"); OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret2"); assertEquals(400, response.getStatusCode()); assertEquals("unauthorized_client", response.getError()); events .expectClientLogin() .client("service-account-cl") .session((String) null) .clearDetails() .error(Errors.INVALID_CLIENT_CREDENTIALS) .user((String) null) .assertEvent(); }
@Test public void authorizationValidRedirectUri() throws IOException { keycloakRule.configure( new KeycloakRule.KeycloakSetup() { @Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { appRealm.getApplicationByName("test-app").addRedirectUri(oauth.getRedirectUri()); } }); oauth.state("mystate"); AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password"); Assert.assertTrue(response.isRedirected()); Assert.assertNotNull(response.getCode()); oauth.verifyCode(response.getCode()); }
@Test public void clientCredentialsDisabledServiceAccount() throws Exception { oauth.clientId("service-account-disabled"); OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret1"); assertEquals(401, response.getStatusCode()); assertEquals("unauthorized_client", response.getError()); events .expectClientLogin() .client("service-account-disabled") .user((String) null) .session((String) null) .removeDetail(Details.USERNAME) .removeDetail(Details.RESPONSE_TYPE) .error(Errors.INVALID_CLIENT) .assertEvent(); }
@Test public void getApplicationSessions() throws Exception { OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password"); assertEquals(200, response.getStatusCode()); OAuthClient.AuthorizationCodeResponse codeResponse = oauth.doLogin("test-user@localhost", "password"); OAuthClient.AccessTokenResponse response2 = oauth.doAccessTokenRequest(codeResponse.getCode(), "password"); assertEquals(200, response2.getStatusCode()); ApplicationResource app = keycloak.realm("test").applications().get("test-app"); assertEquals(2, (long) app.getApplicationSessionCount().get("count")); List<UserSessionRepresentation> userSessions = app.getUserSessions(0, 100); assertEquals(2, userSessions.size()); assertEquals(1, userSessions.get(0).getApplications().size()); }
@Test public void clientCredentialsAuthSuccess() throws Exception { oauth.clientId("service-account-cl"); OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret1"); assertEquals(200, response.getStatusCode()); AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken()); events .expectClientLogin() .client("service-account-cl") .user(userId) .session(accessToken.getSessionState()) .detail(Details.TOKEN_ID, accessToken.getId()) .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) .detail( Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "service-account-cl") .assertEvent(); assertEquals(accessToken.getSessionState(), refreshToken.getSessionState()); System.out.println("Access token other claims: " + accessToken.getOtherClaims()); Assert.assertEquals( "service-account-cl", accessToken.getOtherClaims().get(ServiceAccountConstants.CLIENT_ID)); Assert.assertTrue( accessToken.getOtherClaims().containsKey(ServiceAccountConstants.CLIENT_ADDRESS)); Assert.assertTrue( accessToken.getOtherClaims().containsKey(ServiceAccountConstants.CLIENT_HOST)); OAuthClient.AccessTokenResponse refreshedResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret1"); AccessToken refreshedAccessToken = oauth.verifyToken(refreshedResponse.getAccessToken()); RefreshToken refreshedRefreshToken = oauth.verifyRefreshToken(refreshedResponse.getRefreshToken()); assertEquals(accessToken.getSessionState(), refreshedAccessToken.getSessionState()); assertEquals(accessToken.getSessionState(), refreshedRefreshToken.getSessionState()); events .expectRefresh(refreshToken.getId(), refreshToken.getSessionState()) .user(userId) .client("service-account-cl") .assertEvent(); }
private void grantAccessToken(String login) throws Exception { oauth.clientId("resource-owner"); OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("secret", login, "password"); assertEquals(200, response.getStatusCode()); AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken()); events .expectLogin() .client("resource-owner") .user(userId) .session(accessToken.getSessionState()) .detail(Details.AUTH_METHOD, "oauth_credentials") .detail(Details.RESPONSE_TYPE, "token") .detail(Details.TOKEN_ID, accessToken.getId()) .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) .detail(Details.USERNAME, login) .removeDetail(Details.CODE_ID) .removeDetail(Details.REDIRECT_URI) .removeDetail(Details.CONSENT) .assertEvent(); assertEquals(accessToken.getSessionState(), refreshToken.getSessionState()); OAuthClient.AccessTokenResponse refreshedResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret"); AccessToken refreshedAccessToken = oauth.verifyToken(refreshedResponse.getAccessToken()); RefreshToken refreshedRefreshToken = oauth.verifyRefreshToken(refreshedResponse.getRefreshToken()); assertEquals(accessToken.getSessionState(), refreshedAccessToken.getSessionState()); assertEquals(accessToken.getSessionState(), refreshedRefreshToken.getSessionState()); events .expectRefresh(refreshToken.getId(), refreshToken.getSessionState()) .user(userId) .client("resource-owner") .assertEvent(); }
@Test public void clientCredentialsLogout() throws Exception { oauth.clientId("service-account-cl"); OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret1"); assertEquals(200, response.getStatusCode()); AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken()); events .expectClientLogin() .client("service-account-cl") .user(userId) .session(accessToken.getSessionState()) .detail(Details.TOKEN_ID, accessToken.getId()) .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) .detail( Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "service-account-cl") .detail(Details.CLIENT_AUTH_METHOD, ClientIdAndSecretAuthenticator.PROVIDER_ID) .assertEvent(); HttpResponse logoutResponse = oauth.doLogout(response.getRefreshToken(), "secret1"); assertEquals(204, logoutResponse.getStatusLine().getStatusCode()); events .expectLogout(accessToken.getSessionState()) .client("service-account-cl") .user(userId) .removeDetail(Details.REDIRECT_URI) .assertEvent(); response = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret1"); assertEquals(400, response.getStatusCode()); assertEquals("invalid_grant", response.getError()); events .expectRefresh(refreshToken.getId(), refreshToken.getSessionState()) .client("service-account-cl") .user(userId) .removeDetail(Details.TOKEN_ID) .removeDetail(Details.UPDATED_REFRESH_TOKEN_ID) .error(Errors.INVALID_TOKEN) .assertEvent(); }
@Test public void grantAccessTokenLogout() throws Exception { oauth.clientId("resource-owner"); OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("secret", "test-user@localhost", "password"); assertEquals(200, response.getStatusCode()); AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken()); events .expectLogin() .client("resource-owner") .session(accessToken.getSessionState()) .detail(Details.AUTH_METHOD, "oauth_credentials") .detail(Details.RESPONSE_TYPE, "token") .detail(Details.TOKEN_ID, accessToken.getId()) .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) .removeDetail(Details.CODE_ID) .removeDetail(Details.REDIRECT_URI) .removeDetail(Details.CONSENT) .assertEvent(); HttpResponse logoutResponse = oauth.doLogout(response.getRefreshToken(), "secret"); assertEquals(204, logoutResponse.getStatusLine().getStatusCode()); events .expectLogout(accessToken.getSessionState()) .client("resource-owner") .removeDetail(Details.REDIRECT_URI) .assertEvent(); response = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret"); assertEquals(400, response.getStatusCode()); assertEquals("invalid_grant", response.getError()); events .expectRefresh(refreshToken.getId(), refreshToken.getSessionState()) .client("resource-owner") .removeDetail(Details.TOKEN_ID) .removeDetail(Details.UPDATED_REFRESH_TOKEN_ID) .error(Errors.INVALID_TOKEN) .assertEvent(); }
@Test public void resetPasswordWithPasswordPolicy() throws IOException, MessagingException { keycloakRule.update( new KeycloakRule.KeycloakSetup() { @Override public void config( RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { appRealm.setPasswordPolicy(new PasswordPolicy("length")); } }); loginPage.open(); loginPage.resetPassword(); resetPasswordPage.assertCurrent(); resetPasswordPage.changePassword("login-test"); resetPasswordPage.assertCurrent(); Assert.assertEquals( "You should receive an email shortly with further instructions.", resetPasswordPage.getSuccessMessage()); Assert.assertEquals(1, greenMail.getReceivedMessages().length); MimeMessage message = greenMail.getReceivedMessages()[0]; String body = (String) message.getContent(); String changePasswordUrl = MailUtil.getLink(body); String sessionId = events .expectRequiredAction(EventType.SEND_RESET_PASSWORD) .user(userId) .detail(Details.USERNAME, "login-test") .detail(Details.EMAIL, "*****@*****.**") .assertEvent() .getSessionId(); driver.navigate().to(changePasswordUrl.trim()); updatePasswordPage.assertCurrent(); updatePasswordPage.changePassword("invalid", "invalid"); Assert.assertEquals("Invalid password: minimum length 8", resetPasswordPage.getErrorMessage()); updatePasswordPage.changePassword( "resetPasswordWithPasswordPolicy", "resetPasswordWithPasswordPolicy"); events .expectRequiredAction(EventType.UPDATE_PASSWORD) .user(userId) .session(sessionId) .detail(Details.USERNAME, "login-test") .assertEvent(); Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); events .expectLogin() .user(userId) .detail(Details.USERNAME, "login-test") .session(sessionId) .assertEvent(); oauth.openLogout(); events.expectLogout(sessionId).user(userId).session(sessionId).assertEvent(); loginPage.open(); loginPage.login("login-test", "resetPasswordWithPasswordPolicy"); Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); }
private void resetPassword(String username) throws IOException, MessagingException { loginPage.open(); loginPage.resetPassword(); resetPasswordPage.assertCurrent(); resetPasswordPage.changePassword(username); resetPasswordPage.assertCurrent(); String sessionId = events .expectRequiredAction(EventType.SEND_RESET_PASSWORD) .user(userId) .detail(Details.USERNAME, username) .detail(Details.EMAIL, "*****@*****.**") .assertEvent() .getSessionId(); Assert.assertEquals( "You should receive an email shortly with further instructions.", resetPasswordPage.getSuccessMessage()); Assert.assertEquals(1, greenMail.getReceivedMessages().length); MimeMessage message = greenMail.getReceivedMessages()[0]; String body = (String) message.getContent(); String changePasswordUrl = MailUtil.getLink(body); driver.navigate().to(changePasswordUrl.trim()); updatePasswordPage.assertCurrent(); updatePasswordPage.changePassword("resetPassword", "resetPassword"); events .expectRequiredAction(EventType.UPDATE_PASSWORD) .user(userId) .session(sessionId) .detail(Details.USERNAME, username) .assertEvent(); Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); events .expectLogin() .user(userId) .detail(Details.USERNAME, username) .session(sessionId) .assertEvent(); oauth.openLogout(); events.expectLogout(sessionId).user(userId).session(sessionId).assertEvent(); loginPage.open(); loginPage.login("login-test", "resetPassword"); events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); }
@Override public void open() { oauth.openLoginForm(); assertCurrent(); }
@Before public void before() { oauth.state("mystate"); // keycloak enforces that a state param has been sent by client userId = keycloakRule.getUser("test", "test-user@localhost").getId(); }