Display error page if kerberos token is unavailable
This commit is contained in:
parent
07bda93b81
commit
4b637036ac
9 changed files with 48 additions and 20 deletions
|
@ -2,10 +2,10 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-broker-parent</artifactId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.2.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.broker.provider;
|
|||
|
||||
import org.jboss.resteasy.spi.HttpRequest;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
@ -28,6 +29,7 @@ import javax.ws.rs.core.UriInfo;
|
|||
*/
|
||||
public class AuthenticationRequest {
|
||||
|
||||
private final KeycloakSession session;
|
||||
private final UriInfo uriInfo;
|
||||
private final String state;
|
||||
private final HttpRequest httpRequest;
|
||||
|
@ -35,7 +37,8 @@ public class AuthenticationRequest {
|
|||
private final String redirectUri;
|
||||
private final ClientSessionModel clientSession;
|
||||
|
||||
public AuthenticationRequest(RealmModel realm, ClientSessionModel clientSession, HttpRequest httpRequest, UriInfo uriInfo, String state, String redirectUri) {
|
||||
public AuthenticationRequest(KeycloakSession session, RealmModel realm, ClientSessionModel clientSession, HttpRequest httpRequest, UriInfo uriInfo, String state, String redirectUri) {
|
||||
this.session = session;
|
||||
this.realm = realm;
|
||||
this.httpRequest = httpRequest;
|
||||
this.uriInfo = uriInfo;
|
||||
|
@ -44,6 +47,10 @@ public class AuthenticationRequest {
|
|||
this.clientSession = clientSession;
|
||||
}
|
||||
|
||||
public KeycloakSession getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public UriInfo getUriInfo() {
|
||||
return this.uriInfo;
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-broker-parent</artifactId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.2.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -20,6 +20,11 @@
|
|||
<artifactId>keycloak-broker-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<artifactId>keycloak-login-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.keycloak.broker.kerberos;
|
|||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
@ -14,6 +15,7 @@ import org.keycloak.broker.provider.AbstractIdentityProvider;
|
|||
import org.keycloak.broker.provider.AuthenticationRequest;
|
||||
import org.keycloak.broker.provider.AuthenticationResponse;
|
||||
import org.keycloak.broker.provider.FederatedIdentity;
|
||||
import org.keycloak.login.LoginFormsProvider;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
|
||||
/**
|
||||
|
@ -54,16 +56,16 @@ public class KerberosIdentityProvider extends AbstractIdentityProvider<KerberosI
|
|||
|
||||
// Case when we don't yet have any Negotiate header
|
||||
if (authHeader == null) {
|
||||
return sendNegotiateResponse(null);
|
||||
return sendNegotiateResponse(request, null);
|
||||
}
|
||||
|
||||
String[] tokens = authHeader.split(" ");
|
||||
if (tokens.length != 2) {
|
||||
logger.warn("Invalid length of tokens: " + tokens.length);
|
||||
return sendNegotiateResponse(null);
|
||||
return sendNegotiateResponse(request, null);
|
||||
} else if (!KerberosConstants.NEGOTIATE.equalsIgnoreCase(tokens[0])) {
|
||||
logger.warn("Unknown scheme " + tokens[0]);
|
||||
return sendNegotiateResponse(null);
|
||||
return sendNegotiateResponse(request, null);
|
||||
} else {
|
||||
String spnegoToken = tokens[1];
|
||||
SPNEGOAuthenticator spnegoAuthenticator = createSPNEGOAuthenticator(spnegoToken);
|
||||
|
@ -73,7 +75,7 @@ public class KerberosIdentityProvider extends AbstractIdentityProvider<KerberosI
|
|||
FederatedIdentity federatedIdentity = getFederatedIdentity(spnegoAuthenticator);
|
||||
return AuthenticationResponse.end(federatedIdentity);
|
||||
} else {
|
||||
return sendNegotiateResponse(spnegoAuthenticator.getResponseToken());
|
||||
return sendNegotiateResponse(request, spnegoAuthenticator.getResponseToken());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,16 +96,22 @@ public class KerberosIdentityProvider extends AbstractIdentityProvider<KerberosI
|
|||
* @param negotiateToken token to be send back in response or null if just "WWW-Authenticate: Negotiate" should be sent
|
||||
* @return AuthenticationResponse
|
||||
*/
|
||||
protected AuthenticationResponse sendNegotiateResponse(String negotiateToken) {
|
||||
protected AuthenticationResponse sendNegotiateResponse(AuthenticationRequest request, String negotiateToken) {
|
||||
String negotiateHeader = negotiateToken == null ? KerberosConstants.NEGOTIATE : KerberosConstants.NEGOTIATE + " " + negotiateToken;
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Sending back " + HttpHeaders.WWW_AUTHENTICATE + ": " + negotiateHeader);
|
||||
}
|
||||
|
||||
Response response = Response.status(Response.Status.UNAUTHORIZED)
|
||||
.header(HttpHeaders.WWW_AUTHENTICATE, negotiateHeader)
|
||||
.build();
|
||||
// Error page is rendered just if browser is unable to send Authorization header with SPNEGO token
|
||||
Response response = request.getSession().getProvider(LoginFormsProvider.class)
|
||||
.setRealm(request.getRealm())
|
||||
.setUriInfo(request.getUriInfo())
|
||||
.setError("errorKerberosLogin")
|
||||
.setStatus(Response.Status.UNAUTHORIZED)
|
||||
.createErrorPage();
|
||||
|
||||
response.getMetadata().putSingle(HttpHeaders.WWW_AUTHENTICATE, negotiateHeader);
|
||||
return AuthenticationResponse.fromResponse(response);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-broker-parent</artifactId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.2.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>keycloak-broker-parent</artifactId>
|
||||
<artifactId>keycloak-parent</artifactId>
|
||||
<groupId>org.keycloak</groupId>
|
||||
<version>1.2.0.Beta1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -97,6 +97,8 @@ actionPasswordWarning=You need to change your password to activate your account.
|
|||
actionEmailWarning=You need to verify your email address to activate your account.
|
||||
actionFollow=Please fill in the fields below.
|
||||
|
||||
errorKerberosLogin=Unable to login with Kerberos
|
||||
|
||||
successHeader=Success!
|
||||
errorHeader=Error!
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
|||
|
||||
private String message;
|
||||
private String accessCode;
|
||||
private Response.Status status = Response.Status.OK;
|
||||
private Response.Status status;
|
||||
private List<RoleModel> realmRolesRequested;
|
||||
private MultivaluedMap<String, RoleModel> resourceRolesRequested;
|
||||
private MultivaluedMap<String, String> queryParams;
|
||||
|
@ -218,6 +218,10 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
|||
break;
|
||||
}
|
||||
|
||||
if (status == null) {
|
||||
status = Response.Status.OK;
|
||||
}
|
||||
|
||||
try {
|
||||
String result = freeMarker.processTemplate(attributes, Templates.getTemplate(page), theme);
|
||||
Response.ResponseBuilder builder = Response.status(status).type(MediaType.TEXT_HTML).entity(result);
|
||||
|
@ -246,7 +250,9 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
|||
}
|
||||
|
||||
public Response createErrorPage() {
|
||||
setStatus(Response.Status.INTERNAL_SERVER_ERROR);
|
||||
if (status == null) {
|
||||
status = Response.Status.INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
return createResponse(LoginFormsPages.ERROR);
|
||||
}
|
||||
|
||||
|
|
|
@ -422,7 +422,7 @@ public class AuthenticationBrokerResource {
|
|||
}
|
||||
|
||||
private AuthenticationRequest createAuthenticationRequest(String providerId, String code, RealmModel realm, ClientSessionModel clientSession) {
|
||||
return new AuthenticationRequest(realm, clientSession, this.request, this.uriInfo, code, getRedirectUri(providerId, realm));
|
||||
return new AuthenticationRequest(this.session, realm, clientSession, this.request, this.uriInfo, code, getRedirectUri(providerId, realm));
|
||||
}
|
||||
|
||||
private String getRedirectUri(String providerId, RealmModel realm) {
|
||||
|
|
Loading…
Reference in a new issue