[Fix] Returning 401 if session is invalid, 403 for privilege
This commit is contained in:
parent
ae1de1112d
commit
c79f1d6ae6
|
@ -30,6 +30,7 @@ import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.model.audit.AccessType;
|
import li.strolch.model.audit.AccessType;
|
||||||
import li.strolch.model.audit.Audit;
|
import li.strolch.model.audit.Audit;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
import li.strolch.privilege.base.NotAuthenticatedException;
|
||||||
import li.strolch.privilege.base.PrivilegeException;
|
import li.strolch.privilege.base.PrivilegeException;
|
||||||
import li.strolch.privilege.handler.DefaultPrivilegeHandler;
|
import li.strolch.privilege.handler.DefaultPrivilegeHandler;
|
||||||
import li.strolch.privilege.handler.EncryptionHandler;
|
import li.strolch.privilege.handler.EncryptionHandler;
|
||||||
|
@ -141,7 +142,7 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void isCertificateValid(Certificate certificate) throws PrivilegeException {
|
public void isCertificateValid(Certificate certificate) throws PrivilegeException, NotAuthenticatedException {
|
||||||
assertStarted();
|
assertStarted();
|
||||||
this.privilegeHandler.isCertificateValid(certificate);
|
this.privilegeHandler.isCertificateValid(certificate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package li.strolch.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class StrolchNotAuthenticatedException extends StrolchException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public StrolchNotAuthenticatedException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StrolchNotAuthenticatedException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package li.strolch.privilege.base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown if user is not authenticated, i.e. certificate is not valid anymore, etc.
|
||||||
|
*
|
||||||
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
|
*/
|
||||||
|
public class NotAuthenticatedException extends PrivilegeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param msg
|
||||||
|
* detail on why and where access was denied
|
||||||
|
*/
|
||||||
|
public NotAuthenticatedException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param msg
|
||||||
|
* detail on why and where access was denied
|
||||||
|
* @param e
|
||||||
|
* root exception
|
||||||
|
*/
|
||||||
|
public NotAuthenticatedException(String msg, Exception e) {
|
||||||
|
super(msg, e);
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import li.strolch.privilege.base.AccessDeniedException;
|
import li.strolch.privilege.base.AccessDeniedException;
|
||||||
import li.strolch.privilege.base.InvalidCredentialsException;
|
import li.strolch.privilege.base.InvalidCredentialsException;
|
||||||
|
import li.strolch.privilege.base.NotAuthenticatedException;
|
||||||
import li.strolch.privilege.base.PrivilegeConflictResolution;
|
import li.strolch.privilege.base.PrivilegeConflictResolution;
|
||||||
import li.strolch.privilege.base.PrivilegeException;
|
import li.strolch.privilege.base.PrivilegeException;
|
||||||
import li.strolch.privilege.model.Certificate;
|
import li.strolch.privilege.model.Certificate;
|
||||||
|
@ -1389,7 +1390,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void isCertificateValid(Certificate certificate) {
|
public void isCertificateValid(Certificate certificate) throws PrivilegeException, NotAuthenticatedException {
|
||||||
|
|
||||||
// certificate must not be null
|
// certificate must not be null
|
||||||
if (certificate == null)
|
if (certificate == null)
|
||||||
|
@ -1399,7 +1400,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
PrivilegeContext privilegeContext = this.privilegeContextMap.get(certificate.getSessionId());
|
PrivilegeContext privilegeContext = this.privilegeContextMap.get(certificate.getSessionId());
|
||||||
if (privilegeContext == null) {
|
if (privilegeContext == null) {
|
||||||
String msg = MessageFormat.format("There is no session information for {0}", certificate); //$NON-NLS-1$
|
String msg = MessageFormat.format("There is no session information for {0}", certificate); //$NON-NLS-1$
|
||||||
throw new AccessDeniedException(msg);
|
throw new NotAuthenticatedException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate certificate has not been tampered with
|
// validate certificate has not been tampered with
|
||||||
|
@ -1416,7 +1417,7 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
ZoneId.systemDefault());
|
ZoneId.systemDefault());
|
||||||
if (dateTime.plusHours(1).isBefore(LocalDateTime.now())) {
|
if (dateTime.plusHours(1).isBefore(LocalDateTime.now())) {
|
||||||
invalidateSession(sessionCertificate);
|
invalidateSession(sessionCertificate);
|
||||||
throw new PrivilegeException("Certificate has already expired!"); //$NON-NLS-1$
|
throw new NotAuthenticatedException("Certificate has already expired!"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1433,7 +1434,8 @@ public class DefaultPrivilegeHandler implements PrivilegeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrivilegeContext getPrivilegeContext(Certificate certificate) throws PrivilegeException {
|
public PrivilegeContext getPrivilegeContext(Certificate certificate)
|
||||||
|
throws PrivilegeException, NotAuthenticatedException {
|
||||||
|
|
||||||
// first validate certificate
|
// first validate certificate
|
||||||
isCertificateValid(certificate);
|
isCertificateValid(certificate);
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import li.strolch.privilege.base.AccessDeniedException;
|
import li.strolch.privilege.base.AccessDeniedException;
|
||||||
|
import li.strolch.privilege.base.NotAuthenticatedException;
|
||||||
import li.strolch.privilege.base.PrivilegeConflictResolution;
|
import li.strolch.privilege.base.PrivilegeConflictResolution;
|
||||||
import li.strolch.privilege.base.PrivilegeException;
|
import li.strolch.privilege.base.PrivilegeException;
|
||||||
import li.strolch.privilege.model.Certificate;
|
import li.strolch.privilege.model.Certificate;
|
||||||
|
@ -603,8 +604,10 @@ public interface PrivilegeHandler {
|
||||||
*
|
*
|
||||||
* @throws PrivilegeException
|
* @throws PrivilegeException
|
||||||
* if there is anything wrong with this certificate
|
* if there is anything wrong with this certificate
|
||||||
|
* @throws NotAuthenticatedException
|
||||||
|
* if the certificate has expired
|
||||||
*/
|
*/
|
||||||
public void isCertificateValid(Certificate certificate) throws PrivilegeException;
|
public void isCertificateValid(Certificate certificate) throws PrivilegeException, NotAuthenticatedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link PrivilegeContext} for the given {@link Certificate}. The {@link PrivilegeContext} is an
|
* Returns the {@link PrivilegeContext} for the given {@link Certificate}. The {@link PrivilegeContext} is an
|
||||||
|
@ -617,8 +620,11 @@ public interface PrivilegeHandler {
|
||||||
*
|
*
|
||||||
* @throws PrivilegeException
|
* @throws PrivilegeException
|
||||||
* if there is a configuration error or the {@link Certificate} is invalid
|
* if there is a configuration error or the {@link Certificate} is invalid
|
||||||
|
* @throws NotAuthenticatedException
|
||||||
|
* if the certificate has expired
|
||||||
*/
|
*/
|
||||||
public PrivilegeContext getPrivilegeContext(Certificate certificate) throws PrivilegeException;
|
public PrivilegeContext getPrivilegeContext(Certificate certificate)
|
||||||
|
throws PrivilegeException, NotAuthenticatedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that the given password meets certain requirements. What these requirements are is a decision made by
|
* Validate that the given password meets certain requirements. What these requirements are is a decision made by
|
||||||
|
|
|
@ -40,7 +40,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchComponent;
|
import li.strolch.agent.api.StrolchComponent;
|
||||||
import li.strolch.exception.StrolchException;
|
import li.strolch.exception.StrolchNotAuthenticatedException;
|
||||||
import li.strolch.privilege.base.AccessDeniedException;
|
import li.strolch.privilege.base.AccessDeniedException;
|
||||||
import li.strolch.privilege.base.PrivilegeException;
|
import li.strolch.privilege.base.PrivilegeException;
|
||||||
import li.strolch.privilege.model.Certificate;
|
import li.strolch.privilege.model.Certificate;
|
||||||
|
@ -152,22 +152,26 @@ public class DefaultStrolchSessionHandler extends StrolchComponent implements St
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Certificate validate(String authToken) {
|
public Certificate validate(String authToken) throws StrolchNotAuthenticatedException {
|
||||||
DBC.PRE.assertNotEmpty("authToken must be set!", authToken); //$NON-NLS-1$
|
DBC.PRE.assertNotEmpty("authToken must be set!", authToken); //$NON-NLS-1$
|
||||||
|
|
||||||
Certificate certificate = this.certificateMap.get(authToken);
|
Certificate certificate = this.certificateMap.get(authToken);
|
||||||
|
|
||||||
if (certificate == null)
|
if (certificate == null)
|
||||||
throw new StrolchException(MessageFormat.format("No certificate exists for sessionId {0}", authToken)); //$NON-NLS-1$
|
throw new StrolchNotAuthenticatedException(
|
||||||
|
MessageFormat.format("No certificate exists for sessionId {0}", authToken)); //$NON-NLS-1$
|
||||||
|
|
||||||
return validate(certificate);
|
return validate(certificate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Certificate validate(Certificate certificate) {
|
public Certificate validate(Certificate certificate) throws StrolchNotAuthenticatedException {
|
||||||
this.privilegeHandler.isCertificateValid(certificate);
|
try {
|
||||||
certificate.setLastAccess(new Date());
|
this.privilegeHandler.isCertificateValid(certificate);
|
||||||
return certificate;
|
certificate.setLastAccess(new Date());
|
||||||
|
return certificate;
|
||||||
|
} catch (PrivilegeException e) {
|
||||||
|
throw new StrolchNotAuthenticatedException(e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,6 +18,7 @@ package li.strolch.rest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import li.strolch.exception.StrolchNotAuthenticatedException;
|
||||||
import li.strolch.privilege.base.PrivilegeException;
|
import li.strolch.privilege.base.PrivilegeException;
|
||||||
import li.strolch.privilege.model.Certificate;
|
import li.strolch.privilege.model.Certificate;
|
||||||
import li.strolch.privilege.model.Usage;
|
import li.strolch.privilege.model.Usage;
|
||||||
|
@ -30,9 +31,9 @@ public interface StrolchSessionHandler {
|
||||||
|
|
||||||
public Certificate authenticate(String username, char[] password);
|
public Certificate authenticate(String username, char[] password);
|
||||||
|
|
||||||
public Certificate validate(String authToken);
|
public Certificate validate(String authToken) throws StrolchNotAuthenticatedException;
|
||||||
|
|
||||||
public Certificate validate(Certificate certificate);
|
public Certificate validate(Certificate certificate) throws StrolchNotAuthenticatedException;
|
||||||
|
|
||||||
public void invalidate(Certificate certificate);
|
public void invalidate(Certificate certificate);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@ import javax.ws.rs.ext.Provider;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import li.strolch.exception.StrolchAccessDeniedException;
|
||||||
|
import li.strolch.exception.StrolchNotAuthenticatedException;
|
||||||
import li.strolch.privilege.model.Certificate;
|
import li.strolch.privilege.model.Certificate;
|
||||||
import li.strolch.rest.RestfulStrolchComponent;
|
import li.strolch.rest.RestfulStrolchComponent;
|
||||||
import li.strolch.rest.StrolchRestfulConstants;
|
import li.strolch.rest.StrolchRestfulConstants;
|
||||||
|
@ -105,6 +107,15 @@ public class AuthenticationRequestFilter implements ContainerRequestFilter {
|
||||||
.getComponent(StrolchSessionHandler.class);
|
.getComponent(StrolchSessionHandler.class);
|
||||||
Certificate certificate = sessionHandler.validate(sessionId);
|
Certificate certificate = sessionHandler.validate(sessionId);
|
||||||
requestContext.setProperty(STROLCH_CERTIFICATE, certificate);
|
requestContext.setProperty(STROLCH_CERTIFICATE, certificate);
|
||||||
|
} catch (StrolchNotAuthenticatedException e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
requestContext.abortWith(
|
||||||
|
Response.status(Response.Status.UNAUTHORIZED).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN)
|
||||||
|
.entity("User is not authenticated!").build()); //$NON-NLS-1$
|
||||||
|
} catch (StrolchAccessDeniedException e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN)
|
||||||
|
.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN).entity("User is not authorized!").build()); //$NON-NLS-1$
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e.getMessage());
|
logger.error(e.getMessage());
|
||||||
requestContext.abortWith(
|
requestContext.abortWith(
|
||||||
|
|
Loading…
Reference in New Issue