Can interceptors be executed between authentication and action execution? - grails

Moving from container-managed authentication to the Spring Security plugin in a Grails 3.1.9 app. In the container-managed world, our Grails interceptors executed AFTER authentication for a secured resource. However, with Spring Security, the interceptors (with before() logic) execute with the following sequence:
Call to a secured resource
Interceptor stack intercepts the request, returns true
Redirected to form login page
Successful authentication
Redirection to the requested resource
We have interceptors that should only fire for authenticated users. Is there a way to have interceptors executed between step 4 & 5 instead of this flow? Or is this where our interceptor logic needs to move into Spring Security filters?

It's a little more clear if you look at the flow in a 2.x app since there's a web.xml file where it's more clear what order several of the parts run in, but it's basically the same in 2.x and 3.x.
The plugin's filter chain is registered as one filter and it's configured to run after the grailsWebRequest filter but before the GrailsDispatcherServlet. This is to support annotated controllers that may have URL mappings that are different from the default (e.g. PersonController.show() may map to /person/show but the app could have mapped it to any valid uri (and combination of REST verb(s)), so I need to be able to search the compiled URL mapping instances to figure out what controller action will run for the current request. In the filter, I know what URL is being requested, but not what security rule(s) to apply; if everything was url-based it would be simple and precompiled at startup, but with annotated controllers, I only know what rules apply to controller methods.
The servlet runs after the filters, and that's where the controller is determined and invoked. Interceptors (and Grails filters (not to be confused with servlet Filters) in 2.x) are actually Spring HandlerInterceptors that get composed along with a 'handler' into a HandlerExecutionChain. This is generic enough to work with any type of request but in practice the handler is a controller, so the scope is much narrower than if it were a servlet Filter.
So to get back to your actual question, your best option is to do the work in a filter that's added to the Spring Security filter chain. These are pretty simple to implement and the process is described in the plugin docs.

Related

Spring security based application having both form login and SSO

I have searched enough but I haven't got a clear answer and thus posting this question.
I have an existing application which uses spring security for authentication.
Current implementation uses a custom implementation of UsernamePasswordAuthenticationFilter for doing this.
Thus the flow is something like below(in very simple terms):
inputrequest>DelegatingFilterProxy>LoginUrlAuthenticationEntryPoint>CustomUsernamePasswordAuthenticationFilter>AuthenticationManager>CustomAuthenticationProvider
Now I have a requirement to implement SSO (since the user is already asusmed to be authenticated) in some scenarios.
The requirement states that if I have a specific request parameter present then I need to automatically authenticate the request without bothering about user/password.
So it is same set of resources and I do not have to authenticate user/password if the specific SSO related request parameter is present.
e.g
suppose a resource \test\bus is a secure resource.
if I come from normal way then we need to check if the user is authenticated or nor and force user to put valid user/password
if I come from SSO channel then I need to show the \test\bus resource as the user is already authenticated.
currently all the access restrictions are put through <http> element
e.g the snippet of security-config.xml is as follows:
Query: What options do I have in this case. I can think of below options:
Pre-authenticate the user before spring security framework kicks in. This will mean creating an authentication token and putting in spring context before spring security filter is called. This can be done through another filter which is called before spring security filter chain. I have tested it and it works.
Create another custom security filter which set-up the authentication token. I am not clear if this is correct approach as not sure when do we create multiple custom security filter
Create another custom authentication provider e.g SSOCustomAuthenticationProvider. This provider will be called in the existing current flow as we can have multiple authentication providers to a authentication manager. The only issue is that in order to achieve this I have to change the request url to authentication filter's target url so that spring security doesn't check for authentication.
to explain more,
let's say request uri is /test/bus, I will write a filter which will intercept the request and change it to /test/startlogin. This is currently my CustomUsernamePasswordAuthenticationFilter's target url i.e
<property name="filterProcessesUrl" value="/test/startlogin"/>
The flow will be
inputrequest>DelegatingFilterProxy>LoginUrlAuthenticationEntryPoint>CustomUsernamePasswordAuthenticationFilter>AuthenticationManager>SSOCustomAuthenticationProvider
I have tested this and this works. Is this a valid approach or a hack.
Is there any other viable option available with me.
Thanks for reading this.

How can I access angular2's Http service before I call bootstrap()?

I need to figure out if the user is authenticated or not so when the root component is bootstrapped it will forward the user to /signin or load whatever page they requested. (I plan on doing that by injecting a service with a boolean if it needs to sign on before making any requests).
Angular's docs mention a "Platform Injector" or a "Root Injector". Can I access this to get a Http object? or is it created when bootstrap is called and I need to create my own injector from scratch to get Http?
Before bootstrap the http module is not registered as a valid provider, so you can't use DI to instantiate it.
It's possible that you can find a way to instantiate it manually by importing Http and do
var http = new Http(..)
but you would have to satisfy the input arguments and I am not sure if it's recommended to try to work with modules before the application is in a stable bootstrapped state.
To keep this simple my recommendation would be to do the pre angular check using some other simple http implementation like jquery etc

Spring Boot and Servlet Filter invocation

I am using Spring Boot for my application. Due to a particular need, I have my own Servlet class that extends from the Spring DispatcherServlet. (And I am pretty sure that I won't be the first one that is doing this.)
Everything worked fine until I tried adding authentication/authorization. I setup the authentication/authorization as shown here:
https://github.com/spring-projects/spring-data-examples/tree/master/rest/security
I use the #PreAuthorize annotations on my REST controller methods to restrict access based on the type of operation such as GET/POST.
I get the error: "AuthenticationObject not found in SecurityContextHolder" when I try to POST something. What I did next was compare my application and a working Spring Boot Security example (as in the example above) by stepping through it to see what is happening. I discovered that in the working example, before the doService method of the DispatcherServlet is being invoked, filters such as BasicAuthenticationFilter and others come into the picture. I don't see these filters getting invoked in my application.
Due to the filters not being invoked I don't see the user information or the session-id in the request object at all in my application. I do see that in the working example though. Moreover, I see that in the working example, the request and response objects gets wrapped in a SecurityContextHolder Wrapper from the filter. Since filters don't get invoked in my application, the request/response objects never get wrapped. I suspect that the above error is related to this.
I guess that since I have my own Servlet class that extends the Spring Servlet, it is in essence saying to Spring that I will take control from there. This also means that I will have to do everything that normally Spring does for me.
My questions are :
At what point in Spring Boot do the filters get invoked and how do I achieve
this in my application before the request reaches my custom Servlet?
Do I have to inject them as Beans into my Main class ? And in what order
should they be invoked?
Thanks again,

Username in url but following context path with '/'?

I am developing an Online Recruitment System in Java EE using Servlets and I want to give each user his own unique url by adding username to context path using '/'.
Simply put I want to rewrite my url from /main to /main/username so when people login they can see their username in address bar(just like at stackoverflow or facebook).
Eg. Currently I am redirecting to "/main?username="+username (works fine) using Jquery Ajax but I want to redirect to /main/username.
I tried encodeURL method but '/' makes search for into subdirectory. If anybody think it should work, please give me the syntax.
I have done url mapping in web.xml.(Eg. signin.jsp is mapped to signin uri)
If I understand your question, you want to have a Java EE site like myrecruitingsite.com where you can redirect a user to myrecruitingsite.com/main/<username>. When a request is made to myrecruitingsite.com/main/arg21, or myrecruitingsite.com/main/geoffreywiseman, you'd want the request to go to the same servlet, and you'd like to know which username was requested.
Java servlet mappings don't directly support complex routing patterns in the way that many modern web frameworks do. You can't configure the web.xml to send a request from myrecruitingsite.com/main/<username> to the user profile servlet and myrecruitingsite.com/main/<username>/contact to the contact servlet. You can do wildcard mappings, but all the routing decisions after that you'll have to do outside of the web.xml.
Alternately, you can do URL rewriting (typically with servlet filters) such that the URL requested by the browser is not the final one interpreted by the servlet mapping layer. There are frameworks for this, or you can do it yourself.
Basically, you need to configure the servlet mapping's url pattern with a wildcard, and then query getPathInfo() to find out what the rest of the wildcard was. That alone is pretty simple.
If you're using any one of a wide array of Java web frameworks, there will be facilities for routing and quite possibly a front controller servlet that does what you need already. In that scenario, you'll need to look at the framework's documentation for more information.
On the other hand, if you're doing it yourself using servlets (or even servlets + jsp), you can either just do a wildcard mapping to a single servlet that will grow larger and larger as you add more features to it, or more likely, you'll need to develop your own micro-framework where the servlet acts as a Front Controller servlet and does the routing work and delegates all the subsequent work to plain old java objects (POJOs).
By way of example, your routing servlet could maintain a mapping between url patterns (perhaps specified in java regular expressions) to objects of your own creation that either mimic the servlet interface or another interface of your own creation. That way, you have a servlet that's responsible for the routing decisions bound in the web.xml, and a network of little classes that are responsible for the specifics of a particular request. It's work, but it's not terrifically difficult.
Usually this is achieved using url rewrites on the server. For IIS that means creating a web.config or in apache creating a .htaccess file. You'll need to find the equivalent for your server and it can then be made to parse the directory structure type /username/ into a HTTP GET variable for your application.

Regarding the functionality of struts 2 interceptor and servlets filter

I have a query since I have recently started exploring struts 2 , But please advise that in struts 2 we have interceptors and in servlet's we have filter which also do the same task.Then whats the need of interceptor in struts 2 , what the difference between both.
You took the concept in other way.Struts2 use Filter to intercept each and every request being given to framework.
Filters" are a part of the Servlet Specification; in other words, they are part of the Servlet API.
interceptors are a part of the Struts 2 framework, and are only part of requests handling that is done by the STruts 2 framework.If you are using Struts 2, you should user interceptors for wrapping functionality around your Struts 2 actions.
In Short interceptors are set of reusable component which can be used at various places.Struts2 has created set of interceptors to handle some common tasks being there for each Action request like Data transfer,data conversion,validation etc.
Few differences that I can think of:
Filters are part of Java EE, Interceptors are part of Struts.
Filter cannot be action specific rather they are URL specific(which can mean Action Specific at times), they can be mapped only to Servlet.
Filers are more for deployer (though developers also use them but if deployer has sufficient knowledge they can change during deployment time), deployer can choose configure which Filters are to be invoked for which request, whereas Interceptors are for developers, they decide how to add logic before, after action is executed.
Method filtering is not available in Filters but is possible in Interceptors.
You cannot use Interceptors if you are not handling request by Struts framework say you use a Servlet to handle a specific request.
Edit: Moved comment as part of answer:
Interceptors as a pattern are not Specific to Struts2 and is available in Spring, Hibernate e.t.c

Resources