JAX-RS: How to secure REST endpoints?
Solution 1
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
Solution 2
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 ?
- You have one unprotected URL which does the Authentication, and set the user roles as well..
- Then you return some kind of Token, put it some where in cache which will be expected on every subsequent call..
- Upon new request on other protected resources, you will check if the Token is present in your cache/session store ( you need some mechanism to keep track of valid tokens )
- If token is resent and valid, you do the programmatic Log-in in Spring Security which ensures that you can use all the Security features spring provides, ( Annotations, JSTL Tags etc.. ) !
- Once passed token validation you will get the logged in user details in your controllers ( aka JAX RS resources ) to deal with security further..
- If the token was not valid or not present , it would be trapped by failure end point which would return appropriate response ( 401 )
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
daydreamer
Hello Viewer, Some of the places to see my work are BonsaiiLabs My Website
Updated on March 11, 2020Comments
-
daydreamer about 4 years
I am using
JBoss AS
andJAX-RS
for creatingREST
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 momentWanted
- I would like to add authentication so that when code hitsgetAccount
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 validProblem
- I have never done that so I have no idea how to implement it
- I have googled around a lot and found Jersey examplesUPDATE
- I would like to send authentication credentials with each request and not creating any sessionPlease guide me with one simple working example and I would try to extend from there
-
virgo47 almost 10 yearsThis helped me as well. As I needed to check a few details in different manner, I ended up with "just another demo". While the basics are very similar (can't deny the inspiration started here), I dropped UI and JPA/DB and focused on Spring Security more. Result is here, it's commented, Gradle-based, contains test.sh based on curl. And I wrote a blog post about this topic as well with couple of sequence diagrams. Should be helpful.
-
Amit about 9 yearsHey rakesh, I have checked the angular-rest-springsecurity project on github, i have one question, though all the security related issues are taken care with authorization in picture, but when i refresh the browser once the user is
authenticated
the control seems to be redirected to the login page, even when i just login and click refresh.... do u have any idea about this..?