Alkahna Alkahna - 3 months ago 24
Java Question

Apache Shiro + Authentication issues

I'm using Apache Shiro for my Web Application and I have troubles getting it to work as intended.

What I need is the Authorization part of the Shiro Framework but I can not follow any of those guide as they are all different and I just cant get it to work in my application.

Here is what I want to use the Shiro Framework for:


  • define the existing login.jsp as my login-page

  • define a *.jsp page that is displayed when the login attempt was successfull

  • when the login was not successfull, the user stays at login.jsp but is shown an Error-Message about his failed login attempt

  • all other *.jsp pages exect login.jsp should not be accessible when the user is not logged in



Right now my application does it this way:


  • login form
    action
    parameter calles login.java (servlet)

  • on successfull login -> the page portal.jsp is displayed

  • the page .../portal.jsp can be called without logging in -> This should not be possible in the final version of my application



the following things I figured out so far:

shiro.ini:

[main]
# define login page
authc.loginUrl = /SSP/login.jsp

# name of request parameter with username;
authc.usernameParam = username

# name of request parameter with password;
authc.passwordParam = password

# redirect after successful login
authc.successUrl = /SSP/portal.jsp

[urls]
# enable authc filter for all application pages
/SSP/**=authc


shiro part of my web.xml looks like this:

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>


shiro part of my pom.xml:

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.4</version>
</dependency>


The error I get:

java.lang.IllegalArgumentException: Configuration error.
Specified object [authc] with property [loginUrl] without first defining that object's class.
Please first specify the class property first, e.g. myObject = fully_qualified_class_name and then define additional properties.


EDIT :

It seems this line in shiro.ini did the trick:

authc = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter


But now I have the problem, that the application doesn't use my own login class

login.java:

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String url = "/login.jsp";

// Get Login credentials from Login form
username = request.getParameter("username");
password = request.getParameter("password");

//SecurityManager securityManager = Startup.getSecurityManager();

//2. Get the current Subject:
Subject currentUser = SecurityUtils.getSubject();

//3. Login:
if (!currentUser.isAuthenticated()) {
// create UsernamePasswordToken
UsernamePasswordToken token = new UsernamePasswordToken("cn=" + username + ",ou=People,dc=maxcrc,dc=com", password);
try {
currentUser.login(token);

token.clear();
url = "/portal.jsp";

System.out.println("User [" + currentUser.getPrincipal() +"] logged succesfully");

//4. Create User Session
Session session = currentUser.getSession();

// get user_id
user_id = get_users_id(username);

// create new object of User class
User new_user = new User(user_id, username);

// Set HTTP Session Parameters
session.setAttribute("user", username);
session.setAttribute("user_id", user_id);
session.setAttribute("obj_user", new_user);
session.setAttribute("currentUser", currentUser);

} catch (UnknownAccountException uae) {
System.out.println("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
System.out.println("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
System.out.println("The account for username " + token.getPrincipal() + " is locked. " + "Please contact your administrator to unlock it.");
}
// ... catch more exceptions here (maybe custom ones specific to your application?
catch (AuthenticationException ae) {
System.out.println("ERROR: " + ae);
}
// Done, redirect User to applications main page
request.getRequestDispatcher(url).forward(request, response);
}
}


How can I use my own class (see login.java snippet above) for authentication?

EDIT END

Can anyone provide an example on how to:


  • enable authorization

  • enable page redirection after successful login attempt

  • enable staying at login page but showing error message after failed login attempt

  • make all other pages of the application only accessible if a user is logged in


Answer

I ended up using the code of AuthenticatingFilter and created my own Filter so I can write authc = com.mycompany.ssp.my_own_authFilter dont know if that is how its supposed to be but it seems to work for now

Comments