Implement Authentication Filter (2.1.3.3)

This commit is contained in:
Tobias Eidelpes 2021-04-29 17:37:23 +02:00
parent 1e96417a3f
commit 1363e83aa3
7 changed files with 161 additions and 8 deletions

View File

@ -1,5 +1,8 @@
package dst.ass2.service.api.auth.rest; package dst.ass2.service.api.auth.rest;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import dst.ass2.service.api.auth.AuthenticationException; import dst.ass2.service.api.auth.AuthenticationException;
@ -8,11 +11,12 @@ import dst.ass2.service.api.auth.NoSuchUserException;
/** /**
* The IAuthenticationResource exposes parts of the {@code IAuthenticationService} as a RESTful interface. * The IAuthenticationResource exposes parts of the {@code IAuthenticationService} as a RESTful interface.
*/ */
@Path("auth")
public interface IAuthenticationResource { public interface IAuthenticationResource {
// TODO annotate the class and methods with the correct javax.ws.rs annotations @POST
@Path("authenticate")
Response authenticate(String email, String password) Response authenticate(@FormParam("email") String email, @FormParam("password") String password)
throws NoSuchUserException, AuthenticationException; throws NoSuchUserException, AuthenticationException;
} }

View File

@ -7,7 +7,6 @@ import dst.ass2.service.auth.client.AuthenticationClientProperties;
import dst.ass2.service.auth.client.IAuthenticationClient; import dst.ass2.service.auth.client.IAuthenticationClient;
import io.grpc.ManagedChannel; import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder; import io.grpc.ManagedChannelBuilder;
import io.grpc.StatusRuntimeException;
public class GrpcAuthenticationClient implements IAuthenticationClient { public class GrpcAuthenticationClient implements IAuthenticationClient {
private final ManagedChannel channel; private final ManagedChannel channel;
@ -23,10 +22,10 @@ public class GrpcAuthenticationClient implements IAuthenticationClient {
AuthenticationRequest request = AuthenticationRequest.newBuilder().setEmail(email).setPassword(password).build(); AuthenticationRequest request = AuthenticationRequest.newBuilder().setEmail(email).setPassword(password).build();
AuthenticationResponse response = blockingStub.authenticate(request); AuthenticationResponse response = blockingStub.authenticate(request);
if(response.getStatus().startsWith("NoSuchUserException")) if(response.getStatus().contains("NoSuchUserException"))
throw new NoSuchUserException("User with email " + email + " could not be found"); throw new NoSuchUserException("User with email " + email + " could not be found");
if(response.getStatus().startsWith("AuthenticationException")) if(response.getStatus().contains("AuthenticationException"))
throw new AuthenticationException("Password for user with email " + email + " was incorrect"); throw new AuthenticationException("Password for user with email " + email + " was incorrect");
return response.getToken(); return response.getToken();

View File

@ -11,6 +11,7 @@ import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver; import io.grpc.stub.StreamObserver;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.io.IOException; import java.io.IOException;
@ -20,7 +21,7 @@ import java.io.IOException;
public class GrpcServerRunner extends AuthServiceGrpc.AuthServiceImplBase implements IGrpcServerRunner { public class GrpcServerRunner extends AuthServiceGrpc.AuthServiceImplBase implements IGrpcServerRunner {
@Resource @Resource
private GrpcServerProperties properties; private GrpcServerProperties properties;
@Resource @Inject
private IAuthenticationService authenticationService; private IAuthenticationService authenticationService;
@Override @Override
@ -37,7 +38,7 @@ public class GrpcServerRunner extends AuthServiceGrpc.AuthServiceImplBase implem
AuthenticationResponse response; AuthenticationResponse response;
try { try {
String token = authenticationService.authenticate(request.getEmail(), request.getPassword()); String token = authenticationService.authenticate(request.getEmail(), request.getPassword());
response = AuthenticationResponse.newBuilder().setToken(token).build(); response = AuthenticationResponse.newBuilder().setStatus("").setToken(token).build();
} catch (NoSuchUserException e){ } catch (NoSuchUserException e){
response = AuthenticationResponse.newBuilder().setStatus("NoSuchUserException").build(); response = AuthenticationResponse.newBuilder().setStatus("NoSuchUserException").build();
} catch (AuthenticationException e) { } catch (AuthenticationException e) {

View File

@ -0,0 +1,13 @@
package dst.ass2.service.facade.impl;
import javax.ws.rs.NameBinding;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@NameBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface AuthenticationBinding {
}

View File

@ -0,0 +1,27 @@
package dst.ass2.service.facade.impl;
import dst.ass2.service.api.auth.AuthenticationException;
import dst.ass2.service.api.auth.NoSuchUserException;
import dst.ass2.service.api.auth.rest.IAuthenticationResource;
import dst.ass2.service.auth.client.IAuthenticationClient;
import javax.inject.Inject;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
@Provider
public class AuthenticationResource implements IAuthenticationResource {
@Inject
private IAuthenticationClient authenticationClient;
@Override
public Response authenticate(String email, String password) throws NoSuchUserException, AuthenticationException {
String token = null;
try {
token = authenticationClient.authenticate(email, password);
} catch (NoSuchUserException | AuthenticationException e) {
Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.ok(token).build();
}
}

View File

@ -0,0 +1,36 @@
package dst.ass2.service.facade.impl;
import dst.ass2.service.auth.client.IAuthenticationClient;
import javax.annotation.Priority;
import javax.inject.Inject;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Provider
@Priority(Priorities.AUTHENTICATION)
@AuthenticationBinding
public class Filter implements ContainerRequestFilter {
@Inject
private IAuthenticationClient authenticationClient;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
String header = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
if (header == null) {
requestContext.abortWith(Response.status(Response.Status.BAD_REQUEST).build());
} else {
String[] splitHeader = header.toLowerCase().split("\\s+");
if (splitHeader.length != 2 || !splitHeader[0].equals("bearer"))
requestContext.abortWith(Response.status(Response.Status.BAD_REQUEST).build());
if (!authenticationClient.isTokenValid(splitHeader[1]))
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
}

View File

@ -0,0 +1,73 @@
package dst.ass2.service.facade.impl;
import dst.ass2.service.api.trip.*;
import dst.ass2.service.api.trip.rest.ITripServiceResource;
import org.glassfish.jersey.client.proxy.WebResourceFactory;
import javax.inject.Inject;
import javax.ws.rs.Path;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.net.URI;
@Provider
@Path("trips")
@AuthenticationBinding
public class TripServiceResource implements ITripServiceResource {
@Inject
private URI tripServiceURI;
private final ITripServiceResource tripServiceResource;
public TripServiceResource() {
WebTarget target = ClientBuilder.newClient().target(tripServiceURI);
this.tripServiceResource = WebResourceFactory.newResource(ITripServiceResource.class, target);
}
@Override
public Response createTrip(Long riderId, Long pickupId, Long destinationId) throws EntityNotFoundException, InvalidTripException {
return tripServiceResource.createTrip(riderId, pickupId, destinationId);
}
@Override
public Response confirm(Long tripId) throws EntityNotFoundException, InvalidTripException {
return tripServiceResource.confirm(tripId);
}
@Override
public Response getTrip(Long tripId) throws EntityNotFoundException {
return tripServiceResource.getTrip(tripId);
}
@Override
public Response deleteTrip(Long tripId) throws EntityNotFoundException {
return tripServiceResource.deleteTrip(tripId);
}
@Override
public Response addStop(Long tripId, Long locationId) throws InvalidTripException, EntityNotFoundException {
return tripServiceResource.addStop(tripId, locationId);
}
@Override
public Response removeStop(Long tripId, Long locationId) throws InvalidTripException, EntityNotFoundException {
return tripServiceResource.removeStop(tripId, locationId);
}
@Override
public Response match(Long tripId, MatchDTO matchDTO) throws EntityNotFoundException, DriverNotAvailableException {
return tripServiceResource.match(tripId, matchDTO);
}
@Override
public Response complete(Long tripId, TripInfoDTO tripInfoDTO) throws EntityNotFoundException {
return tripServiceResource.complete(tripId, tripInfoDTO);
}
@Override
public Response cancel(Long tripId) throws EntityNotFoundException {
return tripServiceResource.cancel(tripId);
}
}