【问题标题】:Not able to get proper results using Apache Shiro configuration无法使用 Apache Shiro 配置获得正确的结果
【发布时间】:2011-12-24 19:20:40
【问题描述】:

我正在尝试在我的项目中使用 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]

我正在使用 servlet 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 页面输入凭据时,它都会自动将我带到我输入的凭据的相应页面。例如,如果我在点击 success.jsp 后尝试输入 ROLE_MEMBER 凭据,它会将我带到 success.jsp 页面。但是,如果我在单击相同的 success.jsp 后尝试输入 ROLE_ADMIN,它会根据编写的 servlet 代码自动将我带到 secret.jsp,而不是转到 denied.jsp
  2. 如何在不为每个资源编写单独的 servlet 以显示登录成功或拒绝页面的情况下制作通用代码?

另外,有没有办法在 shiro 中为每个资源创建自定义权限?如果是,那么如何。如果有任何链接,我将不胜感激。

谢谢大家。

【问题讨论】:

    标签: java apache shiro security-roles


    【解决方案1】:

    我想知道为什么您决定在 servlet 中处理身份验证,而不是指南中已经定义的 using the pre-built filter(除此之外,您似乎正在重新加载配置并创建一个新的 SecurityManager在每个请求...)。过滤器应该为您处理 #1 中的详细信息。

    如果你坚持使用 servlet,你需要向 session 添加一个值,或者作为参数添加到 login.jsp 的请求中,告诉它在成功认证后应该将用户重定向到哪里,并在成功后读取该参数用户已通过身份验证。

    关于#2,您只是在成功验证后转发success.jsp。您不是 1) 明确检查用户的角色或允许框架为您这样做。同样,切换到过滤器应该可以为您解决这个问题。

    【讨论】:

    • 我试图理解你在说什么。好的,我会并且只想使用内置的 shiro 过滤器,但在这种情况下,login.jsp 中的 action 属性应该是什么,或者这将如何完成?我正在尝试弄清楚...稍后,我必须使用 JDBC 领域来这样做...
    • 好的...我明白了。我在 login.jsp 的表单标签中保留了 action = "",它就像魔术一样工作。在这种情况下,我不需要关心在哪里检查什么。谢谢您的帮助。很容易。无论如何,其他问题也会回复您...非常感谢。
    • 我对 shiro 有点困惑。在小型测试项目中工作的配置在开发项目中不起作用。这太不一致了。将 action="" 放在 for authentication 过滤器中有时会起作用,有时则不起作用。即使使用基本的身份验证过滤器,它现在也不起作用。
    • @Vishal:如果没有看到配置,我真的无法做出太多诊断。不过,让我印象深刻的是,您的过滤器的 URL 模式可能与所有请求都不匹配。我认为 Shiro 示例中推荐的模式是 /*,它应该对任何请求起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 2016-10-24
    相关资源
    最近更新 更多