Reputation: 91959
I am using JBoss AS
and JAX-RS
for creating REST
endpoints.
Lets say my class looks like
@Path("/users")
public class UserResource {
@GET
public Response getAccount() {
return "hello";
}
}
Now getAccount
is not authenticated at the moment
Wanted
- I would like to add authentication so that when code hits getAccount
the user is authenticated
- I would like the authentication to be driven by annotations instead of XML configurations, if at all possible
- I would like to do the database comparison to see if the user is valid
Problem
- I have never done that so I have no idea how to implement it
- I have googled around a lot and found Jersey examples
UPDATE
- I would like to send authentication credentials with each request and not creating any session
Please guide me with one simple working example and I would try to extend from there
Upvotes: 15
Views: 24634
Reputation: 91959
I solved this with following code.
note Token mechanism will be updated once I do that
I have solved this by modifying the interceptor I have, the following is code
Annotation
@Inherited
@InterceptorBinding
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface SecurityChecked {
}
Resource Class
public class SecureResource {
@GET
@SecurityChecked
public Response getUser() {
return Response.ok("authenticated successfully!").build();
}
}
Interceptor class
@Interceptor
@Provider
@ServerInterceptor
@SecurityChecked
public class SecurityCheckInterceptor implements PreProcessInterceptor, AcceptedByMethod {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityCheckInterceptor.class);
@Nullable
@Override
public ServerResponse preProcess(final HttpRequest request, final ResourceMethod method) throws Failure, WebApplicationException {
final List<String> authToken = request.getHttpHeaders().getRequestHeader("X-AUTH");
if (authToken == null || !isValidToken(authToken.get(0))) {
final ServerResponse serverResponse = new ServerResponse();
serverResponse.setStatus(Response.Status.UNAUTHORIZED.getStatusCode());
return serverResponse;
}
return null;
}
private static boolean isValidToken(@Nonnull final String authToken) {
LOGGER.info("validating token: " + authToken);
return true;
}
@SuppressWarnings("rawtypes")
@Override
public boolean accept(final Class declaring, final Method method) {
// return declaring.isAnnotationPresent(SecurityChecked.class); // if annotation on class
return method.isAnnotationPresent(SecurityChecked.class);
}
}
and then I run my Integration tests by deploying the resource class in JBoss and issuing following commands on command-line
curl --header 'X-AUTH: 1a629d035831feadOOO4uFReLyEW8aTmrCS' http://localhost:8080/market-1.0-SNAPSHOT/rest/login
curl --header 'InvalidHeader: InvalidHeaderValue' http://localhost:8080/market-1.0-SNAPSHOT/rest/login
Upvotes: 11
Reputation: 2287
You need is a Stateless Spring Security configuration in front of your JAX RS end points. I have addressed exact problem you are trying to solve but I don't have my own code to share..
Here is one project which has done the exact thing you are asking, Some wise man has done it all for you ;)
https://github.com/philipsorst/angular-rest-springsecurity
What is the magic ?
Refer Following Link To Understand How Stateless Spring Security is configured.., https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/resources/context.xml
See how a user is validated for the first time and a token is generated.. https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/java/net/dontdrinkandroot/example/angularrestspringsecurity/rest/resources/UserResource.java
Here is the class where programmatic login is performed on every request after token check.. https://github.com/philipsorst/angular-rest-springsecurity/blob/master/src/main/java/net/dontdrinkandroot/example/angularrestspringsecurity/rest/AuthenticationTokenProcessingFilter.java
Upvotes: 15