protected AdminAuth authenticateRealmAdminRequest(HttpHeaders headers) { String tokenString = authManager.extractAuthorizationHeaderToken(headers); if (tokenString == null) throw new UnauthorizedException("Bearer"); JWSInput input = new JWSInput(tokenString); AccessToken token; try { token = input.readJsonContent(AccessToken.class); } catch (IOException e) { throw new UnauthorizedException("Bearer token format error"); } String realmName = token.getAudience(); RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName(realmName); if (realm == null) { throw new UnauthorizedException("Unknown realm in token"); } AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, clientConnection, headers); if (authResult == null) { logger.debug("Token not valid"); throw new UnauthorizedException("Bearer"); } ClientModel client = realm.findClient(token.getIssuedFor()); if (client == null) { throw new NotFoundException("Could not find client for authorization"); } return new AdminAuth(realm, authResult.getToken(), authResult.getUser(), client); }
protected Response handleSamlResponse(String samlResponse, String relayState) { event.event(EventType.LOGOUT); SAMLDocumentHolder holder = extractResponseDocument(samlResponse); StatusResponseType statusResponse = (StatusResponseType) holder.getSamlObject(); // validate destination if (statusResponse.getDestination() != null && !uriInfo.getAbsolutePath().toString().equals(statusResponse.getDestination())) { event.detail(Details.REASON, "invalid_destination"); event.error(Errors.INVALID_SAML_LOGOUT_RESPONSE); return ErrorPage.error(session, Messages.INVALID_REQUEST); } AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, false); if (authResult == null) { logger.warn("Unknown saml response."); event.event(EventType.LOGOUT); event.error(Errors.INVALID_TOKEN); return ErrorPage.error(session, Messages.INVALID_REQUEST); } // assume this is a logout response UserSessionModel userSession = authResult.getSession(); if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) { logger.warn("Unknown saml response."); logger.warn("UserSession is not tagged as logging out."); event.event(EventType.LOGOUT); event.error(Errors.INVALID_SAML_LOGOUT_RESPONSE); return ErrorPage.error(session, Messages.INVALID_REQUEST); } logger.debug("logout response"); Response response = authManager.browserLogout( session, realm, userSession, uriInfo, clientConnection, headers); event.success(); return response; }
protected Response logoutRequest( LogoutRequestType logoutRequest, ClientModel client, String relayState) { SamlClient samlClient = new SamlClient(client); // validate destination if (logoutRequest.getDestination() != null && !uriInfo.getAbsolutePath().equals(logoutRequest.getDestination())) { event.detail(Details.REASON, "invalid_destination"); event.error(Errors.INVALID_SAML_LOGOUT_REQUEST); return ErrorPage.error(session, Messages.INVALID_REQUEST); } // authenticate identity cookie, but ignore an access token timeout as we're logging out // anyways. AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, false); if (authResult != null) { String logoutBinding = getBindingType(); if ("true".equals(samlClient.forcePostBinding())) logoutBinding = SamlProtocol.SAML_POST_BINDING; String bindingUri = SamlProtocol.getLogoutServiceUrl(uriInfo, client, logoutBinding); UserSessionModel userSession = authResult.getSession(); userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING_URI, bindingUri); if (samlClient.requiresRealmSignature()) { userSession.setNote( SamlProtocol.SAML_LOGOUT_SIGNATURE_ALGORITHM, samlClient.getSignatureAlgorithm().toString()); } if (relayState != null) userSession.setNote(SamlProtocol.SAML_LOGOUT_RELAY_STATE, relayState); userSession.setNote(SamlProtocol.SAML_LOGOUT_REQUEST_ID, logoutRequest.getID()); userSession.setNote(SamlProtocol.SAML_LOGOUT_BINDING, logoutBinding); userSession.setNote( SamlProtocol.SAML_LOGOUT_CANONICALIZATION, samlClient.getCanonicalizationMethod()); userSession.setNote( AuthenticationManager.KEYCLOAK_LOGOUT_PROTOCOL, SamlProtocol.LOGIN_PROTOCOL); // remove client from logout requests for (ClientSessionModel clientSession : userSession.getClientSessions()) { if (clientSession.getClient().getId().equals(client.getId())) { clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT.name()); } } logger.debug("browser Logout"); return authManager.browserLogout( session, realm, userSession, uriInfo, clientConnection, headers); } else if (logoutRequest.getSessionIndex() != null) { for (String sessionIndex : logoutRequest.getSessionIndex()) { ClientSessionModel clientSession = session.sessions().getClientSession(realm, sessionIndex); if (clientSession == null) continue; UserSessionModel userSession = clientSession.getUserSession(); if (clientSession.getClient().getClientId().equals(client.getClientId())) { // remove requesting client from logout clientSession.setAction(ClientSessionModel.Action.LOGGED_OUT.name()); // Remove also other clientSessions of this client as there could be more in this // UserSession if (userSession != null) { for (ClientSessionModel clientSession2 : userSession.getClientSessions()) { if (clientSession2.getClient().getId().equals(client.getId())) { clientSession2.setAction(ClientSessionModel.Action.LOGGED_OUT.name()); } } } } try { authManager.backchannelLogout( session, realm, userSession, uriInfo, clientConnection, headers, true); } catch (Exception e) { logger.warn("Failure with backchannel logout", e); } } } // default String logoutBinding = getBindingType(); String logoutBindingUri = SamlProtocol.getLogoutServiceUrl(uriInfo, client, logoutBinding); String logoutRelayState = relayState; SAML2LogoutResponseBuilder builder = new SAML2LogoutResponseBuilder(); builder.logoutRequestID(logoutRequest.getID()); builder.destination(logoutBindingUri); builder.issuer(RealmsResource.realmBaseUrl(uriInfo).build(realm.getName()).toString()); JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder().relayState(logoutRelayState); if (samlClient.requiresRealmSignature()) { SignatureAlgorithm algorithm = samlClient.getSignatureAlgorithm(); KeyManager.ActiveKey keys = session.keys().getActiveKey(realm); binding .signatureAlgorithm(algorithm) .signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()) .signDocument(); } try { if (SamlProtocol.SAML_POST_BINDING.equals(logoutBinding)) { return binding.postBinding(builder.buildDocument()).response(logoutBindingUri); } else { return binding.redirectBinding(builder.buildDocument()).response(logoutBindingUri); } } catch (Exception e) { throw new RuntimeException(e); } }
public void init() { eventStore = session.getProvider(EventStoreProvider.class); account = session .getProvider(AccountProvider.class) .setRealm(realm) .setUriInfo(uriInfo) .setHttpHeaders(headers); AuthenticationManager.AuthResult authResult = authManager.authenticateBearerToken(session, realm, uriInfo, clientConnection, headers); if (authResult != null) { auth = new Auth( realm, authResult.getToken(), authResult.getUser(), client, authResult.getSession(), false); } else { authResult = authManager.authenticateIdentityCookie(session, realm); if (authResult != null) { auth = new Auth( realm, authResult.getToken(), authResult.getUser(), client, authResult.getSession(), true); updateCsrfChecks(); account.setStateChecker(stateChecker); } } String requestOrigin = UriUtils.getOrigin(uriInfo.getBaseUri()); // don't allow cors requests unless they were authenticated by an access token // This is to prevent CSRF attacks. if (auth != null && auth.isCookieAuthenticated()) { String origin = headers.getRequestHeaders().getFirst("Origin"); if (origin != null && !requestOrigin.equals(origin)) { throw new ForbiddenException(); } if (!request.getHttpMethod().equals("GET")) { String referrer = headers.getRequestHeaders().getFirst("Referer"); if (referrer != null && !requestOrigin.equals(UriUtils.getOrigin(referrer))) { throw new ForbiddenException(); } } } if (authResult != null) { UserSessionModel userSession = authResult.getSession(); if (userSession != null) { boolean associated = false; for (ClientSessionModel c : userSession.getClientSessions()) { if (c.getClient().equals(client)) { auth.setClientSession(c); associated = true; break; } } if (!associated) { ClientSessionModel clientSession = session.sessions().createClientSession(realm, client); clientSession.setUserSession(userSession); auth.setClientSession(clientSession); } } account.setUser(auth.getUser()); } boolean eventsEnabled = eventStore != null && realm.isEventsEnabled(); // todo find out from federation if password is updatable account.setFeatures(realm.isIdentityFederationEnabled(), eventsEnabled, true); }