Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9093743
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T23:10:49+00:00 2026-06-16T23:10:49+00:00

(Update 2nd Jan 2013) I’ve now added all the code plus a pom.xml to

  • 0

(Update 2nd Jan 2013) I’ve now added all the code plus a pom.xml to github at https://github.com/AndyWi/GuiceJerseyJettyShiroExample
(End update)

I’m trying to add Form based authentication to my simple application using Shiro. The application uses Guice 3.0, Jersey 1.16 and Shiro 1.2.1, running on embedded Jetty 9.0.0.M4.

My problem is that (as far as I understand) Shiro needs login.jsp to be made available through Guice, and then added to Shiro’s filter chain. However, when I do so, Jetty can’t find login.jsp. When I exclude login.jsp from the Guice filter, Jetty can find the jsp, but then it’s not available to Shiro so the authentication doesn’t work.

So, in my bootstrap code, I use this line to add login.jsp to the Guice Filter:

webAppContext.addFilter(GuiceFilter.class, "/login.jsp", null);

In my ShiroWebModule, I add the login.jsp like so:

addFilterChain("/login.jsp", AUTHC);

I’ve spent a ridiculously long time searching for an answer to this without any hint that anyone else has had the same problem – which means I’m obviously doing something really simple wrong! But I can’t work out what it is. I’d be very grateful if anyone could help me get past this.

I’ve stripped down my project to a small example to demonstrate the problem. All this should do is accept a rest url of /api/uuid, redirect the user to login.jsp, accept any username/password combination for authentication, and then return a new UUID from the /api/uuid service; the user should also remain logged in for future requests. Here’s the full code in the hope that it will help someone out there spot the problem:

Bootstrap:

package eg.guicejerseyjettyshiro;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.webapp.WebAppContext;
import com.google.inject.servlet.GuiceFilter;
import eg.guicejerseyjettyshiro.modules.EgGuiceServletContextListener;

public class Bootstrap {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8081);

        WebAppContext webAppContext = new WebAppContext();
        webAppContext.setContextPath("/");
        webAppContext.setResourceBase("src/main/webapp/");
        webAppContext.setParentLoaderPriority(true);

        webAppContext.addEventListener(new EgGuiceServletContextListener());

        webAppContext.addFilter(GuiceFilter.class, "/api/*", null);

        // **** Shiro needs login.jsp to go through the GuiceFilter,
        // but Jetty can't find the jsp when this happens. Commenting
        // out this line lets Jetty find the jsp, but Shiro can't see it:
        webAppContext.addFilter(GuiceFilter.class, "/login.jsp", null);

        webAppContext.addServlet(DefaultServlet.class, "/");

        server.setHandler(webAppContext);

        server.start();
        server.join();
    }

}

EgGuiceServletContextListener:

package eg.guicejerseyjettyshiro.modules;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceServletContextListener;

public class EgGuiceServletContextListener extends GuiceServletContextListener {

    private ServletContext servletContext;

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        this.servletContext = servletContextEvent.getServletContext();
        super.contextInitialized(servletContextEvent);
    }

    @Override
    protected Injector getInjector() {
        return Guice.createInjector(
                new EgJerseyServletModule(),
                new EgShiroWebModule(this.servletContext));
    }

}

EgJerseyServletModule:

package eg.guicejerseyjettyshiro.modules;

import org.apache.shiro.guice.web.GuiceShiroFilter;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
import eg.guicejerseyjettyshiro.dao.UuidDao;
import eg.guicejerseyjettyshiro.services.UuidService;

public class EgJerseyServletModule extends JerseyServletModule {

    @Override
    protected void configureServlets() {
        bindings();
        filters();
    }

    private void bindings() {
        bind(UuidDao.class);
        bind(UuidService.class);
    }

    private void filters() {
        filter("/*").through(GuiceShiroFilter.class);
        filter("/*").through(GuiceContainer.class);
    }

}

EgShiroWebModule:

package eg.guicejerseyjettyshiro.modules;

import javax.servlet.ServletContext;
import org.apache.shiro.guice.web.ShiroWebModule;
import com.google.inject.name.Names;
import eg.guicejerseyjettyshiro.realms.EgAuthorizingRealm;

public class EgShiroWebModule extends ShiroWebModule {

    public EgShiroWebModule(ServletContext servletContext) {
        super(servletContext);
    }

    @Override
    protected void configureShiroWeb() {
        bindConstant().annotatedWith(Names.named("shiro.globalSessionTimeout")).to(30000L);

        bindRealm().to(EgAuthorizingRealm.class).asEagerSingleton();

        addFilterChain("/login.jsp", AUTHC);
        addFilterChain("/api/*", AUTHC);
    }

}

EgAuthorizingRealm:

package eg.guicejerseyjettyshiro.realms;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class EgAuthorizingRealm extends AuthorizingRealm {

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
        System.out.println("In EgAuthorizingRealm.doGetAuthenticationInfo for: " + upToken.getUsername() + "/" + new String(upToken.getPassword()) + " - remember=" + upToken.isRememberMe());
        return new SimpleAuthenticationInfo(upToken.getUsername(), upToken.getPassword(), getName());
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        System.out.println("In EgAuthorizingRealm.doGetAuthorizationInfo");
        // Doing nothing just now
        return null;
    }

}

UuidService:

package eg.guicejerseyjettyshiro.services;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import eg.guicejerseyjettyshiro.dao.UuidDao;

@Path("/api/uuid")
@Produces({MediaType.APPLICATION_XML})
public class UuidService {

    private final UuidDao uuidDao;

    @Inject
    public UuidService(UuidDao uuidDao) {
        this.uuidDao = uuidDao;
    }

    @GET
    public String get() {
        Subject currentUser = SecurityUtils.getSubject();
        System.out.println("UuidService current user: " + currentUser.getPrincipal().toString());
        return "<uuid>" + this.uuidDao.generateUuid().toString() + "</uuid>";
    }

}

UuidDao:

package eg.guicejerseyjettyshiro.dao;

import java.util.UUID;

public class UuidDao {

    public UUID generateUuid() {
        return UUID.randomUUID();
    }
}

login.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Please Login</title>
</head>
<body>

<form name="loginForm" action="" method="post">
<table align="left" border="0" cellspacing="0" cellpadding="3">
    <tr>
        <td>Username:</td>
        <td><input type="text" name="username" maxlength="30"></td>
    </tr>
    <tr>
        <td>Password:</td>
        <td><input type="password" name="password" maxlength="30"></td>
    </tr>
    <tr>
        <td colspan="2" align="left"><input type="checkbox" name="rememberMe"><font size="2">Remember Me</font></td>
    </tr>
    <tr>
        <td colspan="2" align="right"><input type="submit" name="submit" value="Login"></td>
    </tr>
</table> 
</form>

</body>
</html>

OK, I think that’s all. I realise this is quite long, so thanks very much for reading this far. This has been driving me crazy, so any help you can give me will be very appreciated!

Thanks,
Andy.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T23:10:51+00:00Added an answer on June 16, 2026 at 11:10 pm

    This has been answered thanks to Milan Baran on the Shiro users forums. The github repo has been updated, here’s a quick summary in case anyone is interested:

    In the Bootstrap class, we only need one GuiceFilter added, for /*, and the default server is not needed at all. So, that becomes:

    public static void main(String[] args) throws Exception {
        Server server = new Server(8081);
    
        WebAppContext webAppContext = new WebAppContext();
        webAppContext.setContextPath("/");
        webAppContext.setResourceBase("src/main/webapp/");
        webAppContext.setParentLoaderPriority(true);
    
        webAppContext.addEventListener(new EgGuiceServletContextListener());
    
        webAppContext.addFilter(GuiceFilter.class, "/*", null);
    
        server.setHandler(webAppContext);
    
        server.start();
        server.join();
    }
    

    We then need to update the jersey servlet module to bind DefaultServlet and GuiceContainer, and change the filter through GuiceContainer to be through /api instead of /*, like so:

    public class EgJerseyServletModule extends JerseyServletModule {
    
    @Override
    protected void configureServlets() {
        bindings();
        filters();
    }
    
    private void bindings() {
        bind(UuidDao.class);
        bind(UuidService.class);
        bind(DefaultServlet.class).asEagerSingleton();
        bind(GuiceContainer.class).asEagerSingleton();
        serve("/*").with(DefaultServlet.class);
    }
    
    private void filters() {
        filter("/*").through(GuiceShiroFilter.class);
        filter("/api/*").through(GuiceContainer.class);
    }
    
    }
    

    Thanks everyone for helping with this!
    Andy.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Update: I reported this as a bug to Apple and they fixed it! All
UPDATE: I'm getting this error: (No route matches /docs/index.html... ) when accessing admin.example.com/docs/index.html The
I have 2 views in my app 1st view: tableview and button(update) 2nd view:
Please move down to the 2nd update. I didn't want to change the previous
I am using JSF1.1 in that, I want to update 2nd selectOneMenu from 1st
Update I've found the problem, the exception came from a 2nd field on the
( 2nd Update from 2012/12/06 -- new protocol, a sligtly different view) The question
Update: Is there a way to achieve what I'm trying to do in an
update: I mistyped 2 variables...so embarrassing. thanks everyone for the effort! sorry i find
UPDATE: I've been playing around with this more, and it seems like tmux's clear-history

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.