Не удается получить правильные результаты при использовании конфигурации Apache Shiro - PullRequest
0 голосов
/ 09 ноября 2011

Я пытаюсь использовать apache shiro в своем проекте, так как мне нужно создать механизм на основе ролей в моем проекте.Я создал демонстрационный проект со следующими конфигурациями ...

Я создал следующие файлы в своем проекте -

index.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>Shiro Web Test</title>
</head>
<body>
<h1>This is a test for Shiro Web Framework</h1>

<a href = "success.jsp">Click Here!</a>
</body>
</html>

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>Shiro Web Test : Login Page</title>
</head>
<body>
<%! String errorMessage = null; %>
<% 
errorMessage = (String) request.getAttribute("shiroLoginFailure");
if (errorMessage != null) { %>
<font color="red">Invalid Login: ${errorMessage}</font><br/>
<font color="black"><h3>Enter login information...</h3></font>
<% } else { %>
<font color="black"><h3>Enter login information...</h3></font>
<% } %>

<form action="loginTest.do" method="POST">
<table>
<tr>
<td>Username:</td>
<td><input type="text" name="username" placeholder="username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" placeholder="password" /></td>
</tr>
</table>
<input type="checkbox" value="true" name="rememberMe" />Remember Me?<br />
<input type="submit" value="Sign In" />
</form>
</body>
</html>

success.jsp denied.jsp logout.jsp showUser.jsp

Моя shiro.ini конфигурация выглядит следующим образом -

# =======================
# Shiro INI configuration
# =======================

[main]
authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
roles = org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
authc.loginUrl = /login.jsp
authc.failureKeyAttribute = shiroLoginFailure
roles.unauthorizedUrl = /denied.jsp

[users]
admin = password, ROLE_ADMIN
member = password, ROLE_MEMBER

[roles]
ROLE_ADMIN = *

[urls]
/success.jsp = authc, roles[ROLE_MEMBER]
/secret.jsp = roles[ROLE_ADMIN]

Я использую сервлет LoginTestServlet.java для отправки на страницу login.jsp или success.jsp после успешной / неудачной аутентификации -

public class LoginTestServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        generateResponse(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        generateResponse(request, response);
    }

    protected void generateResponse(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        UserCredentials user = new UserCredentials();
        user.setUserName(request.getParameter("username"));
        user.setPassword(request.getParameter("password"));

        if (user.getUserName() != null && user.getPassword() != null) {
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            SecurityManager securityManager = factory.getInstance();
            SecurityUtils.setSecurityManager(securityManager);
            Subject currentUser = SecurityUtils.getSubject();

            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());

            try {
                currentUser.login(token);
                Session session = currentUser.getSession();
                session.setAttribute("user", user.getUserName());
            } catch (UnknownAccountException uae) {
                request.setAttribute("shiroLoginFailure", uae.getMessage());
                System.err.println("Exception type: " + uae.getClass().getName());
                System.err.println("Error due to: " + uae.getMessage());
            } catch (IncorrectCredentialsException iae) {
                request.setAttribute("shiroLoginFailure", iae.getMessage());
                System.err.println("Exception type: " + iae.getClass().getName());
                System.err.println("Error due to: " + iae.getMessage());
            } catch (LockedAccountException lae) {
                request.setAttribute("shiroLoginFailure", lae.getMessage());
                System.err.println("Exception type: " + lae.getClass().getName());
                System.err.println("Error due to: " + lae.getMessage());
            } catch (AuthenticationException ae) {
                request.setAttribute("shiroLoginFailure", ae.getMessage());
                System.err.println("Exception type: " + ae.getClass().getName());
                System.err.println("Error due to: " + ae.getMessage());
            } catch (Exception e) {
                request.setAttribute("shiroLoginFailure", e.getMessage());
                System.err.println("Exception type: " + e.getClass().getName());
                System.err.println("Error due to: " + e.getMessage());
            }

            RequestDispatcher view = null;

            if (currentUser.isAuthenticated() && currentUser.hasRole("ROLE_MEMBER")) {
                view = request.getRequestDispatcher("success.jsp");
                view.forward(request, response);
            } else if (currentUser.isAuthenticated() && currentUser.hasRole("ROLE_ADMIN")) {
                view = request.getRequestDispatcher("secret.jsp");
                view.forward(request, response);
            } else {
                view = request.getRequestDispatcher("login.jsp");
                view.forward(request, response);
            }
        }
    }//end of generateResponse()

}//end of class

Я использую TOMCAT 6.0.

Моя проблема -

  1. Всякий раз, когда я пытаюсь ввести учетные данные на странице login.jsp , она автоматически переводит меня на соответствующую страницу для ввода учетных данных, которые я ввожу.Например, если я попытаюсь ввести учетные данные ROLE_MEMBER после нажатия на success.jsp , это приведет меня к странице success.jsp .Но если я попытаюсь ввести ROLE_ADMIN после нажатия на тот же success.jsp , это автоматически приведет меня к secret.jsp согласно коду сервлета, написанному вместо перехода на denied.jsp .
  2. Как создать универсальный код без написания отдельного сервлета для каждого ресурса, чтобы показать успешный вход в систему или страницу с отказом?

Также есть ли способ создатьпользовательские разрешения в сиро для каждого ресурса?Если да, то как.Если есть какая-либо ссылка на это, я был бы вам благодарен.

Спасибо всем.

1 Ответ

0 голосов
/ 09 ноября 2011

Мне интересно, почему вы решили обработать аутентификацию внутри сервлета, а не , используя предварительно встроенный фильтр , как уже определено в руководстве (помимо прочего, вы, кажется, перезагружаете конфигурация и создание нового SecurityManager на каждый запрос ...). Фильтр должен обрабатывать детали в # 1 для вас.

Если вы настаиваете на использовании сервлета, вам необходимо добавить значение либо в сеанс, либо в качестве параметра в запрос к login.jsp, который указывает, куда следует перенаправить пользователя после успешной аутентификации, и прочитать этот параметр, как только пользователь аутентифицирован.

Что касается # 2, вы просто пересылаете success.jsp после успешной аутентификации. Вы не 1) явно проверяете роли пользователя или не позволяете платформе сделать это за вас. Опять же, переключение на фильтр должно решить эту проблему для вас.

...