You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by mircea <mi...@yahoo.ca> on 2012/12/05 15:00:39 UTC

Why is Shiro assuming that you already have a server running?

Hello,

I'm wondering why is SHIRO assuming that the Guice injector must be created
after the server (in my case Jetty) is created.

You can only use Shiro after the ServletContext is available. I think this
is a wrong assumption because you can also use Guice to wire the entire
application, including the server. This means the ServletContext is not
available at the injector creation time. So, no out-of-the-box solution in
this case.

How could I solve this problem? How can I initialize Shiro in a web
application which is using Guice for the server creation?

Thanks,



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Why-is-Shiro-assuming-that-you-already-have-a-server-running-tp7578017.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Why is Shiro assuming that you already have a server running?

Posted by mircea <mi...@yahoo.ca>.
Could be that I miss something then. What you said is actually what I'm also
trying to do:
Do the authentication based on the Cookie and use AOP for JAXRS resources.

I started by modifying the org.apache.shiro.guice.web package in order to
create a setter on the WebGuiceEnvironment class to set the ServletContext.
I extend a bit the GuiceShiroFilter in order to create an
AuthenticationToken based on the received cookie and login the current
subject (the authentication is resolved in a specialized Realm).

One other thing I had to do, was to set a DefaultWebSessionManager on the
created DefaultWebSecurityManager, otherwise I get into some exceptions :

java.lang.IllegalArgumentException: SessionContext must be an HTTP
compatible implementation.

The solution I got from
http://shiro-user.582556.n2.nabble.com/Subject-Builder-Exception-SessionContext-td7577512.html

In this way, the resource authorization seems to work. What I observed is
that it still works even if I don't explicitly set the ServletContext in the
WebGuiceEnvironment. Which means the ServletContext is not even used so the
created Jira issue makes even more sense. 

I checkout the SVN repository and I hope I'll have a bit of time to create a
patch for this JIRA issue you created. Would be good to have a solution for
this, so I don;t have to maintain it with the next Shiro releases.

Thanks,



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Why-is-Shiro-assuming-that-you-already-have-a-server-running-tp7578017p7578040.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Why is Shiro assuming that you already have a server running?

Posted by Jared Bunting <ja...@peachjean.com>.
> I actually want to use automatic authentication based on cookies and REST
> resources authorization with AOP. This means I need to hook somehow in the
> RequestHandler and authenticate the user before it reaches the resources. As
> far as I know this is not supported by Shiro, but it is a real use case and
> I would like to use Shiro because of all the cool features it has.

Could you describe exactly what you're trying to do here?  All of my 
applications actually do authentication based on headers and uses AOP 
for authorization on JAXRS resource methods.  I use basic Shiro AOP for 
the authorization piece and a custom servlet filter for the 
header-based authentication.  Cookie-based authentication shouldn't be 
entirely different...just a different servlet filter.

-Jared

Re: Why is Shiro assuming that you already have a server running?

Posted by mircea <mi...@yahoo.ca>.
I already started to work with solution number 1. This means I had to change
the web module, in such a way that I can pass the ServletContext to the
WebGuiceEnvironment (this was the only place where the Servletcontext is
actually used). I did this by exposing the WebGuiceEnvironment and getting
it from the injector when the ServletContext becomes available:


getInjector().getInstance(Key.get(WebGuiceEnvironment.class)).setServletContext(servletContextEvent.getServletContext());

I don't know yet if this approach has other side effects that I cannot see
right now.

I actually want to use automatic authentication based on cookies and REST
resources authorization with AOP. This means I need to hook somehow in the
RequestHandler and authenticate the user before it reaches the resources. As
far as I know this is not supported by Shiro, but it is a real use case and
I would like to use Shiro because of all the cool features it has.

I'll take a look also to the solution you provided and see if this suits
better. Looks indeed a bit simpler.

PS: Right now, the jetty server is bound to a Provider which configures the
jetty server.The ServletContextListener is bounded to a
GuiceServletContextListener which gets the injector injected and is not
created there. The server Provider is also taking care of registering a
ServletContextHandler, which in turn registers the GuiceFilter. This is so
because it's an embedded server set-up, without any web.xml file.



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Why-is-Shiro-assuming-that-you-already-have-a-server-running-tp7578017p7578023.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Why is Shiro assuming that you already have a server running?

Posted by Jared Bunting <ja...@peachjean.com>.
Basically, it is assuming that because that was the use case I was 
working with.  I have added SHIRO-401 
(https://issues.apache.org/jira/browse/SHIRO-401) to allow the passing 
of a provider, which should enable your use case.

In the meantime, there are a couple of options.

1. Copy ShiroWebModule into your project and change it.
2. Write an implementation of the ServletContext interface that 
deletages all of its calls to "provider.get()".  Pass that 
implementation

Neither is particularly attractive, I know.  I've included my first 
thoughts at implementing #2.

Thanks,
Jared

PS.  Could you share how you are using Guice to create the Jetty server 
with Shiro?  I think this would be an interesting sample to add to the 
project.



import com.google.inject.Provider;

import javax.servlet.ServletContext;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ServletContextProxy implements InvocationHandler {
    private final Provider<ServletContext> contextProvider;

    public ServletContextProxy(Provider<ServletContext> 
contextProvider) {
        this.contextProvider = contextProvider;
    }

    public Object invoke(Object proxy, Method method, Object[] args) 
throws Throwable {
        return method.invoke(contextProvider.get(), args);
    }

    public static ServletContext 
createInstance(Provider<ServletContext> contextProvider) {
        return (ServletContext) 
Proxy.newProxyInstance(contextProvider.getClass().getClassLoader(), new 
Class[]{ServletContext.class}, new 
ServletContextProxy(contextProvider));
    }
}


On Wed 05 Dec 2012 08:00:39 AM CST, mircea wrote:
> Hello,
>
> I'm wondering why is SHIRO assuming that the Guice injector must be created
> after the server (in my case Jetty) is created.
>
> You can only use Shiro after the ServletContext is available. I think this
> is a wrong assumption because you can also use Guice to wire the entire
> application, including the server. This means the ServletContext is not
> available at the injector creation time. So, no out-of-the-box solution in
> this case.
>
> How could I solve this problem? How can I initialize Shiro in a web
> application which is using Guice for the server creation?
>
> Thanks,
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/Why-is-Shiro-assuming-that-you-already-have-a-server-running-tp7578017.html
> Sent from the Shiro User mailing list archive at Nabble.com.