You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Stephen Colebourne <sc...@joda.org> on 2014/03/14 16:45:01 UTC

Embedded web server startup and static SecurityManager

Hi Shiro team,
I am currently integrating Shiro into our application.

We have our own component-based configuration system which needs to
operate as follows:
- start user database component
- start Shiro PasswordService component
- start Shiro SeurityManager component
- start embedded Jetty web server

I can quite happily perform the first three steps, but when I start
the web server it currently reads a Shiro INI file in
IniWebEnvironment and sets up a second SecurityManager. Instead, I
want the existing static SecurityManager to be used. (I want to
continue using the INI file to setup the filters from the [main] and
[urls] section).

Have I missed something, or do I just have to hack around with the
WebEnvironment to write a subclass that re-uses the static
SecurityManager?

In the embedded Jetty scenario, I think most users would want to
re-use a static SecurityManager that has been separately created.

Also, as a detail, PasswordMatcher could really do with an additional
constructor that takes the PasswordService.

thanks
Stephen

Re: Embedded web server startup and static SecurityManager

Posted by Shan Syed <sh...@gmail.com>.
thanks guys

I really hope 2.0 favours composition :)
chasing functionality through class hierarchy is a young man's game



On Thu, Jul 17, 2014 at 8:50 AM, Stephen Colebourne <sc...@joda.org>
wrote:

> The security manager is setup once up front including the realms.
>
> Imagine a main method that did this:
> - setup realm connected to database
> - setup static security manager
> - start embedded Jetty
> - embedded jetty re-uses the previously setup static security manager
>
> The example code shows how hard I found it to get the static security
> manager re-used in the web environment.
>
> Stephen
>
>
> On 15 July 2014 16:45, shan <sh...@gmail.com> wrote:
> > Stephen, thanks for the code snippet - one question though, where in this
> > mechanism are you inserting your custom Realm into the Security Manager?
> >
> >
> >
> > --
> > View this message in context:
> http://shiro-user.582556.n2.nabble.com/Embedded-web-server-startup-and-static-SecurityManager-tp7579754p7580084.html
> > Sent from the Shiro User mailing list archive at Nabble.com.
>

Re: Embedded web server startup and static SecurityManager

Posted by Stephen Colebourne <sc...@joda.org>.
The security manager is setup once up front including the realms.

Imagine a main method that did this:
- setup realm connected to database
- setup static security manager
- start embedded Jetty
- embedded jetty re-uses the previously setup static security manager

The example code shows how hard I found it to get the static security
manager re-used in the web environment.

Stephen


On 15 July 2014 16:45, shan <sh...@gmail.com> wrote:
> Stephen, thanks for the code snippet - one question though, where in this
> mechanism are you inserting your custom Realm into the Security Manager?
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/Embedded-web-server-startup-and-static-SecurityManager-tp7579754p7580084.html
> Sent from the Shiro User mailing list archive at Nabble.com.

Re: Embedded web server startup and static SecurityManager

Posted by domfarr <do...@gmail.com>.
Here is what I use in my embedded server app. Hope this helps.

public class ShiroEnvironmentListener implements ServletContextListener {
    private final RosserApplicationConfiguration configuration;
    private final EnvironmentLoaderListener environmentLoaderListener;
    private final Realm rosserRealm;
    private final SystemAudit systemAudit;
    private final CustomerFolderDAO customerFolderDAO;

    public ShiroEnvironmentListener(RosserApplicationConfiguration
configuration, EnvironmentLoaderListener environmentLoaderListener, Realm
rosserRealm, SystemAudit systemAudit, CustomerFolderDAO customerFolderDAO) {
        this.configuration = configuration;
        this.environmentLoaderListener = environmentLoaderListener;
        this.rosserRealm = rosserRealm;
        this.systemAudit = systemAudit;
        this.customerFolderDAO = customerFolderDAO;
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext servletContext = sce.getServletContext();
        servletContext.setInitParameter("shiroConfigLocations",
configuration.getShiroConfigLocations());
        environmentLoaderListener.contextInitialized(sce);
        WebEnvironment webEnvironment =
WebUtils.getWebEnvironment(servletContext);
        WebSecurityManager webSecurityManager =
webEnvironment.getWebSecurityManager();
        ((RealmSecurityManager) webSecurityManager).setRealm(rosserRealm);

        ModularRealmAuthenticator authenticator =
(ModularRealmAuthenticator) ((DefaultWebSecurityManager)
webSecurityManager).getAuthenticator();

       
authenticator.setAuthenticationListeners(Lists.<AuthenticationListener>newArrayList(new
SystemAuditAuthenticationListener(systemAudit, customerFolderDAO)));
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        environmentLoaderListener.contextDestroyed(sce);
    }

}

shan wrote
> Stephen, thanks for the code snippet - one question though, where in this
> mechanism are you inserting your custom Realm into the Security Manager?





--
View this message in context: http://shiro-user.582556.n2.nabble.com/Embedded-web-server-startup-and-static-SecurityManager-tp7579754p7580089.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Embedded web server startup and static SecurityManager

Posted by shan <sh...@gmail.com>.
Stephen, thanks for the code snippet - one question though, where in this
mechanism are you inserting your custom Realm into the Security Manager?



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Embedded-web-server-startup-and-static-SecurityManager-tp7579754p7580084.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Embedded web server startup and static SecurityManager

Posted by Stephen Colebourne <sc...@joda.org>.
This is what I had to write to achieve this. Perhaps the developers of
Shiro might consider finding a way to make it easier?
Stephen

public final class ShiroSecurityEnvironmentLoader extends
EnvironmentLoaderListener {

  @Override
  protected WebEnvironment createEnvironment(ServletContext servletContext) {
    ShiroWebEnvironment environment = new ShiroWebEnvironment();
    environment.setServletContext(servletContext);
    String configLocations =
StringUtils.trimToNull(servletContext.getInitParameter(CONFIG_LOCATIONS_PARAM));
    if (configLocations != null) {
      environment.setConfigLocations(configLocations);
    }
    environment.init();
    return environment;
  }

  //-------------------------------------------------------------------------
  /**
   * Apache Shiro web environment that re-uses the static manager.
   */
  private final class ShiroWebEnvironment extends IniWebEnvironment {
    @Override
    protected WebSecurityManager createWebSecurityManager() {
      ShiroFactory factory = new ShiroFactory();
      factory.setIni(getIni());
      WebSecurityManager wsm = (WebSecurityManager) factory.getInstance();
      Map<String, ?> beans = factory.getBeans();
      if (!CollectionUtils.isEmpty(beans)) {
        this.objects.putAll(beans);
      }
      return wsm;
    }
  }

  //-------------------------------------------------------------------------
  /**
   * Apache Shiro factory that re-uses the static manager.
   */
  private class ShiroFactory extends WebIniSecurityManagerFactory {
    @Override
    protected SecurityManager createDefaultInstance() {
      try {
        SecurityManager sm = SecurityUtils.getSecurityManager();
        if (sm instanceof WebSecurityManager) {
          return sm;
        }
        return super.createDefaultInstance();

      } catch (UnavailableSecurityManagerException ex) {
        return super.createDefaultInstance();
      }
    }
  }

}





On 14 March 2014 16:29, Dominic Farr <do...@gmail.com> wrote:
> I agree constructor over setter every time; but that is another
> conversation.
>
> If you are using EmbeddedJetty which configures shiro's
> EnvironmentLoaderListener, I would suggest replacing, or encapsulating the
> shiro EnvironmentLoaderListener with your own ServletContextListener and
> inject your SecurityManager instance into that.
>
> I've done something similar with a Dropwizard project that uses an jetty and
> it works nicely.
>
> -d
>
>
>
>
> On 14 March 2014 16:15, Stephen Colebourne <sc...@joda.org> wrote:
>>
>> On 14 March 2014 15:59, Dominic Farr <do...@gmail.com> wrote:
>> > Not sure I fully understand your "component-based configuration system",
>> > so
>> > can you include your configuration at least?
>>
>> The INI configuration is uninteresting - a [urls] section setting up
>> permissions mapped to urls.
>>
>> The component-based config is complex to explain, but could be reduced
>> to the following actual java class (using psuedo code rather than real
>> code):
>>
>> public void initSystem() {
>>   // bits I am happy with
>>   MyUserDAO dao = ...
>>   MyUserRealm realm = new MyUserRealm(dao);
>>   SecurityManager sm = new DefaultWebSecurityManager(realm);
>>   SecurityUtils.setSecurityManager(sm);
>>   // bit that goes wrong
>>   Jetty jetty = new EmbeddedJetty();
>> }
>>
>> It goes wrong because embedded jetty reads web.xml and web.xml
>> includes EnvironmentLoaderListener, and that starts its own
>> SecurityManager. I want it to re-use the static one from
>> SecurityUtils.
>>
>>
>> > On PasswordMatcher question, I'm assuming you mean
>> >
>> > https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/authc/credential/PasswordMatcher.html
>> > Shiro uses setter inject over constructor. I think because that is how
>> > ini
>> > works. On this class there are get/set PasswordService.
>>
>> Yes I mean that PasswordMatcher. Not everyone uses the INI format for
>> everything. I'm creating an instanceof PasswordMatcher
>> programmatically, and it is a (minor) pain because it needs three
>> lines instead of one (in order to call the setter). I would consider
>> it good practice for Shiro to provide for setting common elements via
>> the constructor as well as via setters, particularly when the
>> PasswordService is the only setter and it is mandatory!
>>
>> Stephen
>>
>>
>> > On 14 March 2014 15:45, Stephen Colebourne <sc...@joda.org> wrote:
>> >>
>> >> Hi Shiro team,
>> >> I am currently integrating Shiro into our application.
>> >>
>> >> We have our own component-based configuration system which needs to
>> >> operate as follows:
>> >> - start user database component
>> >> - start Shiro PasswordService component
>> >> - start Shiro SeurityManager component
>> >> - start embedded Jetty web server
>> >>
>> >> I can quite happily perform the first three steps, but when I start
>> >> the web server it currently reads a Shiro INI file in
>> >> IniWebEnvironment and sets up a second SecurityManager. Instead, I
>> >> want the existing static SecurityManager to be used. (I want to
>> >> continue using the INI file to setup the filters from the [main] and
>> >> [urls] section).
>> >>
>> >> Have I missed something, or do I just have to hack around with the
>> >> WebEnvironment to write a subclass that re-uses the static
>> >> SecurityManager?
>> >>
>> >> In the embedded Jetty scenario, I think most users would want to
>> >> re-use a static SecurityManager that has been separately created.
>> >>
>> >> Also, as a detail, PasswordMatcher could really do with an additional
>> >> constructor that takes the PasswordService.
>> >>
>> >> thanks
>> >> Stephen
>> >
>> >
>
>

Re: Embedded web server startup and static SecurityManager

Posted by Dominic Farr <do...@gmail.com>.
I agree constructor over setter every time; but that is another
conversation.

If you are using EmbeddedJetty which configures shiro's
EnvironmentLoaderListener, I would suggest replacing, or encapsulating the
shiro EnvironmentLoaderListener with your own ServletContextListener and
inject your SecurityManager instance into that.

I've done something similar with a Dropwizard project that uses an jetty
and it works nicely.

-d




On 14 March 2014 16:15, Stephen Colebourne <sc...@joda.org> wrote:

> On 14 March 2014 15:59, Dominic Farr <do...@gmail.com> wrote:
> > Not sure I fully understand your "component-based configuration system",
> so
> > can you include your configuration at least?
>
> The INI configuration is uninteresting - a [urls] section setting up
> permissions mapped to urls.
>
> The component-based config is complex to explain, but could be reduced
> to the following actual java class (using psuedo code rather than real
> code):
>
> public void initSystem() {
>   // bits I am happy with
>   MyUserDAO dao = ...
>   MyUserRealm realm = new MyUserRealm(dao);
>   SecurityManager sm = new DefaultWebSecurityManager(realm);
>   SecurityUtils.setSecurityManager(sm);
>   // bit that goes wrong
>   Jetty jetty = new EmbeddedJetty();
> }
>
> It goes wrong because embedded jetty reads web.xml and web.xml
> includes EnvironmentLoaderListener, and that starts its own
> SecurityManager. I want it to re-use the static one from
> SecurityUtils.
>
>
> > On PasswordMatcher question, I'm assuming you mean
> >
> https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/authc/credential/PasswordMatcher.html
> > Shiro uses setter inject over constructor. I think because that is how
> ini
> > works. On this class there are get/set PasswordService.
>
> Yes I mean that PasswordMatcher. Not everyone uses the INI format for
> everything. I'm creating an instanceof PasswordMatcher
> programmatically, and it is a (minor) pain because it needs three
> lines instead of one (in order to call the setter). I would consider
> it good practice for Shiro to provide for setting common elements via
> the constructor as well as via setters, particularly when the
> PasswordService is the only setter and it is mandatory!
>
> Stephen
>
>
> > On 14 March 2014 15:45, Stephen Colebourne <sc...@joda.org> wrote:
> >>
> >> Hi Shiro team,
> >> I am currently integrating Shiro into our application.
> >>
> >> We have our own component-based configuration system which needs to
> >> operate as follows:
> >> - start user database component
> >> - start Shiro PasswordService component
> >> - start Shiro SeurityManager component
> >> - start embedded Jetty web server
> >>
> >> I can quite happily perform the first three steps, but when I start
> >> the web server it currently reads a Shiro INI file in
> >> IniWebEnvironment and sets up a second SecurityManager. Instead, I
> >> want the existing static SecurityManager to be used. (I want to
> >> continue using the INI file to setup the filters from the [main] and
> >> [urls] section).
> >>
> >> Have I missed something, or do I just have to hack around with the
> >> WebEnvironment to write a subclass that re-uses the static
> >> SecurityManager?
> >>
> >> In the embedded Jetty scenario, I think most users would want to
> >> re-use a static SecurityManager that has been separately created.
> >>
> >> Also, as a detail, PasswordMatcher could really do with an additional
> >> constructor that takes the PasswordService.
> >>
> >> thanks
> >> Stephen
> >
> >
>

Re: Embedded web server startup and static SecurityManager

Posted by Stephen Colebourne <sc...@joda.org>.
On 14 March 2014 15:59, Dominic Farr <do...@gmail.com> wrote:
> Not sure I fully understand your "component-based configuration system", so
> can you include your configuration at least?

The INI configuration is uninteresting - a [urls] section setting up
permissions mapped to urls.

The component-based config is complex to explain, but could be reduced
to the following actual java class (using psuedo code rather than real
code):

public void initSystem() {
  // bits I am happy with
  MyUserDAO dao = ...
  MyUserRealm realm = new MyUserRealm(dao);
  SecurityManager sm = new DefaultWebSecurityManager(realm);
  SecurityUtils.setSecurityManager(sm);
  // bit that goes wrong
  Jetty jetty = new EmbeddedJetty();
}

It goes wrong because embedded jetty reads web.xml and web.xml
includes EnvironmentLoaderListener, and that starts its own
SecurityManager. I want it to re-use the static one from
SecurityUtils.


> On PasswordMatcher question, I'm assuming you mean
> https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/authc/credential/PasswordMatcher.html
> Shiro uses setter inject over constructor. I think because that is how ini
> works. On this class there are get/set PasswordService.

Yes I mean that PasswordMatcher. Not everyone uses the INI format for
everything. I'm creating an instanceof PasswordMatcher
programmatically, and it is a (minor) pain because it needs three
lines instead of one (in order to call the setter). I would consider
it good practice for Shiro to provide for setting common elements via
the constructor as well as via setters, particularly when the
PasswordService is the only setter and it is mandatory!

Stephen


> On 14 March 2014 15:45, Stephen Colebourne <sc...@joda.org> wrote:
>>
>> Hi Shiro team,
>> I am currently integrating Shiro into our application.
>>
>> We have our own component-based configuration system which needs to
>> operate as follows:
>> - start user database component
>> - start Shiro PasswordService component
>> - start Shiro SeurityManager component
>> - start embedded Jetty web server
>>
>> I can quite happily perform the first three steps, but when I start
>> the web server it currently reads a Shiro INI file in
>> IniWebEnvironment and sets up a second SecurityManager. Instead, I
>> want the existing static SecurityManager to be used. (I want to
>> continue using the INI file to setup the filters from the [main] and
>> [urls] section).
>>
>> Have I missed something, or do I just have to hack around with the
>> WebEnvironment to write a subclass that re-uses the static
>> SecurityManager?
>>
>> In the embedded Jetty scenario, I think most users would want to
>> re-use a static SecurityManager that has been separately created.
>>
>> Also, as a detail, PasswordMatcher could really do with an additional
>> constructor that takes the PasswordService.
>>
>> thanks
>> Stephen
>
>

Re: Embedded web server startup and static SecurityManager

Posted by Dominic Farr <do...@gmail.com>.
Not sure I fully understand your "component-based configuration system", so
can you include your configuration at least?

On PasswordMatcher question, I'm assuming you mean
https://shiro.apache.org/static/1.2.2/apidocs/org/apache/shiro/authc/credential/PasswordMatcher.html

Shiro uses setter inject over constructor. I think because that is how ini
works. On this class there are get/set PasswordService.

-d



On 14 March 2014 15:45, Stephen Colebourne <sc...@joda.org> wrote:

> Hi Shiro team,
> I am currently integrating Shiro into our application.
>
> We have our own component-based configuration system which needs to
> operate as follows:
> - start user database component
> - start Shiro PasswordService component
> - start Shiro SeurityManager component
> - start embedded Jetty web server
>
> I can quite happily perform the first three steps, but when I start
> the web server it currently reads a Shiro INI file in
> IniWebEnvironment and sets up a second SecurityManager. Instead, I
> want the existing static SecurityManager to be used. (I want to
> continue using the INI file to setup the filters from the [main] and
> [urls] section).
>
> Have I missed something, or do I just have to hack around with the
> WebEnvironment to write a subclass that re-uses the static
> SecurityManager?
>
> In the embedded Jetty scenario, I think most users would want to
> re-use a static SecurityManager that has been separately created.
>
> Also, as a detail, PasswordMatcher could really do with an additional
> constructor that takes the PasswordService.
>
> thanks
> Stephen
>