I'm working on a web application using React on the frontend and Java on the backend. From the frontend, I call different resources from the backend, where I have various classes providing #GET methods.
For every method, I'm always using the same check to determine if the user is authorized based on their session ID. That's a very repetitive way to accomplish this. This is especially true when creating a new #GET method, as I have to always remember to add this isUserAuthorized check.
My first thought was using an abstract class for the resources to centralize some of the code, but here I'd still have to add the check to each method.
Is there a way I can implement the authorization check for all HTTP requests, without needing to repeat this code?
Related
I'm trying to understand this example project which uses Google's OAuth library to let users login with their Google account.
Specifically, I'm trying to understand the relationship between Oauth2AuthorizationCodeServlet.java and Oauth2CallbackServlet.java. I know that Google's OAuth 2.0 library uses them to kick off the authorization flow and to handle the result after the user logs in, and I've read through the documentation for both abstract classes, but I'm wondering why both classes need to repeat the same logic?
Both classes define getUserId() functions which return the same value.
Both classes define initializeFlow() functions which return the same value.
Both classes define getRedirectUri() functions which return the same value.
The code works fine, and I can see that the functions are called in this order:
Oauth2AuthorizationCodeServlet#getUserId()
Oauth2AuthorizationCodeServlet#initializeFlow()
Oauth2AuthorizationCodeServlet#getRedirectUri()
Oauth2CallbackServlet#initializeFlow()
Oauth2CallbackServlet#getRedirectUrl()
Oauth2CallbackServlet#getUserId()
Oauth2CallbackServlet#onSuccess()
But I'm wondering why the repeated functions in Oauth2CallbackServlet are necessary.
Why can't Google's OAuth 2.0 library use the values returned by the first class? Would it ever make sense for the corresponding functions to return different values? For example, would it ever make sense for their getRedirectUrl() functions to return different URLs?
Here is simplified diagram of google oauth login flow.
No 1. here represents Oauth2AuthorizationCodeServlet
No 2. here represents Oauth2CallbackServlet
Those are two different servlets, responsible for separate parts of login flow. 1 - redirects user to google login form with some url params like redirect url.
2 - handles callback after user finished with login, this servlet can access user info from google, perform actions on user behalf in google etc.
To answer your questions:
Why can't Google's OAuth 2.0 library use the values returned by the first class?
Those are two separate servlets - it would be incorrect to perform communication between two separate servlets.
Would it ever make sense for the corresponding functions to return different values? For example, would it ever make sense for their getRedirectUrl() functions to return different URLs?
In common scenario i don't think it makes sense to return different values from those servlets, but maybe some exotic scenario exists, where you have to support multiple google login callback urls for different use cases.
I want to refresh a JWT every time a controller method is called without having to add a method to every single controller call. Is there a method I can override?
I'm using a Java API.
I want to refresh a JWT every time...
This should be avoided unless you really know what you are going to do.
Use Refresh Tokens Only to refresh your JWT Access Tokens. For more information, read this article and this question & answer (both)
If the primary concern is only about refreshing the tokens, then server should not be bothered about this mechanism intuitively. Such request must be raised from client applications/client of server/web clients/etc.. that they want to refresh the token.
For Eg, If JWT access Token is having 10min lifetime, and refresh token is having 720hrs of lifetime,
then client must call a refresh token request silently before the expiration time. (in this case, each 8-9 mins should be ok)
or else, if you don't want to make calls after every 8-9 mins since the user might not be actively using, then you can write some interceptors which checks the expiry of token before making HTTP calls, if token is expired (or about to expire) then they should call refresh token API first, get new token and then continue the normal HTTP call, all this on client side.
This stackoverflow question is kind of doing similar thing with respect to angular framework ( at client side).
That's okay.. but, Still I want to do it on server side, What are the choices?
You can use Aspect Oriented Programming model for this kind of stuff, and happy part is, it's available in Spring Framework.
Read this for basic idea to start over.
Or
Use Filter Interceptors of HttpServlets to manipulate requests/responses.
Read this nice article to get some idea about it.
Hope it helps, at least, in learning. :)
I'd like to secure a simple rest web service developed using Jersey using Spring OAuth v1.0a, and I have a questions about it. First, a brief doubt: I've found some examples involving Spring-MVC, is it mandatory to include it? As I'm trying to make my application as light as possibile, it would be nice if I could leave Spring-MVC out.
Apart from that, my biggest issue is about token handling, and particularly about dealing with the steps that lead a user to access an OAuth protected area. From what I got to understand, trying to access a protected area automatically triggers the token generation process, starting from the creation of the unauthorized request token. Unfortunately, this workflow doesn't fit my needs as the scenario I have to deal with involves a user which is already in possess of an authorized access token, and only needs to provide it in order to be granted access to a protected resource. Would it be possibile to override the token generation mechanism with a token retrieval (from a POST/GET for instance) and verification process?
Thank you very much for your effort.
EDIT: (trying to explain things more clearly)
Assume this is the part in my XML where I describe my resource:
<oauth:resource id="OAuthExperimentsRestrictedArea"
key="thisIsExactlyTheConsumerKey"
secret="...andThisIsExactlyTheSecret"
request-token-url="http://localhost:8080/OauthExperiments/oauth/request_token"
user-authorization-url="http://localhost:8080/OauthExperiments/oauth/confirm_access"
access-token-url="http://localhost:8080/OauthExperiments/oauth/access_token" />
What I can't really get to understand is how or where should I pass an already valid access token in case I had it. By trying to directly access the resource via a simple direct link not providing any token, my application would begin the token creation process redirecting me first to request-token-url, next to user-authorization-url and finally to access-token-url. What I need to achieve is the possibility to skip this when I already have a valid token, but what I'm missing is how to do that, where to pass the token (is there a default bean for that? should I pass it as a parameter with a particular name?).
My goal is to have the possibility to delegate even external services for token verification, so what I'm ultimately trying to find is some kind of hook for such procedure. I hope I've explained the whole scenario clearly enough.
That's 2 questions?
Spring MVC is not needed for securing a resource (it's all Spring Security via Servlet Filters).
The second question is about what to do if you have a valid access token and as a consumer you want to send valid requests and access protected resources. A new token would not need to be generated if the request is already authorized.
The answer to the second question is that you need to populate the OAuthSecurityContext (via a thread local managed by OAuthSecurityContextHolder). Obviously you need to be careful to clear it when you are finished. Normally this context is populated by a filter (OAuthConsumerContextFilter) so you can see how that manages the context and copy it. I can't say I like this model much, but that's the way it was implemented (the OAuth2 implementation changed quite a while ago, before 1.0).
I've seen several GWT code excerpts where the developer extended DefaultRequestTransport and gave it custom functionality. One such example is in this SO question regarding authentication/login filters. But I have seen several others besides this one example.
My question: when & why does someone need to extend this class and override its methods? (In other words, what does this class do, what services do its methods perform, and why would I need to customize them?)
In that one example, the createRequestCallback method was overridden. According to the Javadocs on that method, it's purpose is to:
Create a RequestCallback that maps the HTTP response onto the TransportReceiver interface.
This is still sort of a cryptic explanation to me. Could someone please give me a layman's explanation for what scenarios it would be beneficial to extend this class and override 1+ of its methods?
RequestFactory does not depend on a specific "transport" mechanism; it deals with JSON representations of requests and responses but the way they're exchanged and transferred is out of scope, and deferred to a RequestTransport.
The DefaultRequestTransport uses a RequestBuilder to a given (but configurable) URL; because it uses RequestBuilder, it can only be used in a GWT client (to be compiled to JavaScript). There's also the UrlRequestTransport which uses a java.net.HttpURLConnection and can be used on any client running in a JVM (a server making a call to another server, an Android application, a desktop Java application, etc.)
In theory (because I never tried it and never heard someone else tried it), you could make a RequestTransport that uses Comet or WebSockets, or whichever transport you'd like. Of course, the server side would have to be adapted too (SimpleRequestProcessor can easily reused outside the RequestFactoryServlet; this is a similar separation of concerns)
Back to DefaultRequestTransport: it uses RequestBuilder and provides a few hooks that you can override to customize how it works. The most common use-case is to intercept all requests to add some request header (e.g. credentials) and/or all responses to handle specific HTTP responses before decoding the JSON-encoded RequestFactory response (e.g. intercept "unauthorized" response to ask the user to sign in).
DefaultRequestTransport works as an adapter between the RequestFactory API and the RequestBuilder one, and createRequestCallback is one half of it responsible for adapting the response.
In the example shown they need to extend DefaultRequestTransport in order to inspect all RF server responses and catch 401 status (SC_UNAUTHORIZED) which means that the request was rejected in the server side because the user has not a valid session, and then redirect the user to the application login page.
I've used DefaultRequestTransport as well for changing the requestUrl (the default is set to gwtRequest), so as I can set filters based on the url pattern: for instance authenticated RF services go to /myapp/gwtRequest or non-authenticated RF services go to /myapp/anonymousRequest etc.
I also have a customized RequestTransport using modified versions of RequestBuilder and XMLHttpRequest able to monitor onprogress events, very helpful for large requests.
You could extend it to send customized headers used for doing CORS authentication or whatever.
In summary RequestTransport is the way to modify the client transport layer of RF.
Suppose I have a set of JAX-RS locators and sublocators, like the following:
#Path("/users")
public class UserListResource {
#Path("/{id}")
public UserResource getCustomer(#PathParam("id") int id) {
// Find and return user object
}
}
public class UserResource {
#GET
public String get() {...}
}
For example, a UserResource object with the ID 5 would have the path "/users/5". In my system, I have several different resources.
Now the question is: How can the server figure out the path of a given resource? Can I do this programmatically via some JAX-RS API or do I have to implement code that uses reflection? (I know how to do the latter, but would prefer the other approach.)
At the point when I need to know the path, I do not have a request object at all. For example, I have a timer which does some background processing, then changes some entities in the domain model, then informs all clients about the changed entities (including their paths).
I know that within the scope of a request, I can inject a UriInfo object that provides this, but I need to know the path in advance (to inform clients of a change that did not necessarily happen through the JAX-RS resource).
I don't want to repeat the path information in another place, and I also don't want to have a set of path fragment constants for each resource type (in this case "/users" and "/{id}").
As I read your question, you need to build a URI knowing only the resource class and the id parameter.
It can be done using the UriBuilder class as in:
UriBuilder builder=UriBuilder.fromResource(UserListResource.class);
URI uri=builder.path(UserListResource.class,"getCustomer").build(5);
It uses reflection under the hood, so it is not so easy to refactor, but it is all it is available at the moment.
Overall, be aware that something sounds rather strange with the architecture of your application. It's hard to put a finger on, but the pattern of questions you are asking is raising a number of red flags about how you're going about this. Be aware that if you are seeking to create a RESTful API to your application that you may need to stop, take a few steps back, and rethink what you are trying to do.
To your explicit questions…
Now the question is: How can the server figure out the path of a given resource? Can I do this programmatically via some JAX-RS API or do I have to implement code that uses reflection? (I know how to do the latter, but would prefer the other approach.)
The server knows the path, as that's always supplied by the user and is used to navigate through the collection of resource classes that make up your application. If you need a UriInfo instance for a particular call, you should inject it as part of that specific call:
#GET
public String get(#Context UriInfo info) {...}
Any information required from the outer context (e.g., what the resource's ID is) is best passed in during construction. You can reparse it out of the URL (obtainable from the UriInfo) again, but that's probably the wrong approach.
Otherwise, if you're doing something much more complex then you need to be more specific in your question.
At the point when I need to know the path, I do not have a request object at all. For example, I have a timer which does some background processing, then changes some entities in the domain model, then informs all clients about the changed entities (including their paths).
I know that within the scope of a request, I can inject a UriInfo object that provides this, but I need to know the path in advance (to inform clients of a change that did not necessarily happen through the JAX-RS resource).
How are you going to have the clients be informed? There's normally no mechanism to push messages from the server to the clients, and clients are typically firewalled so that they can't directly host a service.
Theoretically, you could associate (explicitly, by URL) each resource with its own RSS feed to which a client could listen to if they chose. You wouldn't be able to force clients to listen, but you could give them the option to do so. If you go this route, you don't need to know the UriInfo “ahead of time” as the location information will be present at key times (i.e., at resource creation) and afterwards you're just referring to something that you have control over.
But that's just one way to do it and it adds a lot of complexity; you'd only do it if it was critical to your application. It's often simpler to just have clients poll from time to time. (Note that some sorts of modifications are inherently very destructive; particularly altering the ID or deleting the resource. Don't expect things to cope smoothly with those.)
I don't want to repeat the path information in another place, and I also don't want to have a set of path fragment constants for each resource type (in this case "/users" and "/{id}").
Tough. Repeating information in multiple places, provided you draw it consistently from a single source, is a common practice. There's nothing actually wrong with it.
As I understand your question, you want to know the path as the request is coming in but before it hits your resource; are you open to using Servlet Filters?
JAX-RS specific filters are only supported in 2.0
For the record: after I had posted the question, I thought about our architecture a bit more and came to the conclusion that sending URLS is not as useful as I thought. The application has to know some details about the application structure anyway:
Continuing the example above: even if the client did not know the URL pattern for individual users, it must assume that there is a list of users and know its URL; it also has hard-coded knowledge what dialog to display for editing a user etc.
So all in all, attempting to tell the client (most) URLs it needs is not worth the effort. Instead, we decided to go with a custom API definition file which includes data about the resource contents and their URL scheme. This file is used to generate the following:
the server-side resource classes with the correct JAX-RS annotations
a URL scheme specification document for other developers to code against
classes for our own client (including the URL know how, e.g. user with ID 5 has the URL ...), so we don't have to worry about inconsistencies between our client and server.
This approach has the following advantages:
The need for the server to figure out the URLs from the annotations vanishes, as the client can now do that on its own once it receives a notification that includes the object ID.
We don't have to worry about inconsistencies between our client and the server, as all information is drawn from a single source.
We have one source for the API definition under version control which can be used to verify backwards compatibility with older releases.
Note:
I would probably not claim that the resulting API stays "faithful" to the idea of RESTful webservices, but it works for us and the elements that it borrows from "actual" REST architectural style should make the API clearer and easier to learn than a traditional contract-first webservice.