Java 无法使用Apache Shiro配置获得正确的结果

Java 无法使用Apache Shiro配置获得正确的结果,java,apache,shiro,security-roles,Java,Apache,Shiro,Security Roles,我试图在我的项目中使用ApacheShiro,因为我必须在我的项目中创建基于角色的机制。我用以下配置创建了一个演示项目 我在我的项目中创建了以下文件- 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/

我试图在我的项目中使用ApacheShiro,因为我必须在我的项目中创建基于角色的机制。我用以下配置创建了一个演示项目

我在我的项目中创建了以下文件-

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>
<%@ 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>
身份验证成功/失败后,我正在使用servletLoginTestServlet.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
公共类LoginTestServlet扩展了HttpServlet{
受保护的void doGet(HttpServletRequest请求,HttpServletResponse响应)抛出ServletException,IOException{
生成响应(请求、响应);
}
受保护的void doPost(HttpServletRequest请求、HttpServletResponse响应)引发ServletException、IOException{
生成响应(请求、响应);
}
受保护的void generateResponse(HttpServletRequest请求、HttpServletResponse响应)引发IOException、ServletException{
UserCredentials user=新的UserCredentials();
user.setUserName(request.getParameter(“用户名”);
user.setPassword(request.getParameter(“密码”));
if(user.getUserName()!=null&&user.getPassword()!=null){
Factory Factory=new-InSecurityManagerFactory(“类路径:shiro.ini”);
SecurityManager SecurityManager=factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject currentUser=SecurityUtils.getSubject();
UsernamePasswordToken=新的UsernamePasswordToken(user.getUserName(),user.getPassword());
试一试{
currentUser.login(令牌);
会话会话=currentUser.getSession();
session.setAttribute(“user”,user.getUserName());
}捕获量(阿联酋未知){
request.setAttribute(“ShiroginFailure”,uae.getMessage());
System.err.println(“异常类型:+uae.getClass().getName());
System.err.println(“由于:+uae.getMessage()引起的错误”);
}捕获(不正确的凭证例外){
request.setAttribute(“ShiroginFailure”,iae.getMessage());
System.err.println(“异常类型:+iae.getClass().getName());
System.err.println(“由于:+iae.getMessage()引起的错误”);
}捕获(锁定帐户例外lae){
setAttribute(“ShiroginFailure”,lae.getMessage());
System.err.println(“异常类型:”+lae.getClass().getName());
System.err.println(“由于“+lae.getMessage()”引起的错误);
}捕获(AuthenticationException ae){
request.setAttribute(“ShiroginFailure”,ae.getMessage());
System.err.println(“异常类型:+ae.getClass().getName());
System.err.println(“由于:“+ae.getMessage()”引起的错误);
}捕获(例外e){
setAttribute(“ShiroginFailure”,e.getMessage());
System.err.println(“异常类型:+e.getClass().getName());
System.err.println(“由于以下原因导致的错误:”+e.getMessage());
}
RequestDispatcher视图=null;
if(currentUser.isAuthenticated()&¤tUser.hasRole(“角色\成员”)){
view=request.getRequestDispatcher(“success.jsp”);
视图。转发(请求、响应);
}else if(currentUser.isAuthenticated()&¤tUser.hasRole(“角色\管理员”)){
view=request.getRequestDispatcher(“secret.jsp”);
视图。转发(请求、响应);
}否则{
view=request.getRequestDispatcher(“login.jsp”);
视图。转发(请求、响应);
}
}
}//发电机响应结束()
}//下课
我正在使用Tomcat6.0

我的问题是-

  • 每当我试图在login.jsp页面输入凭据时,它会自动将我带到相应的页面以获取我输入的凭据。例如,如果我在单击success.jsp后尝试输入角色\ U成员凭据,我将进入success.jsp页面。但是,如果我在单击相同的success.jsp后尝试进入ROLE_ADMIN,它会根据编写的servlet代码自动将我转到secret.jsp,而不是转到denied.jsp
  • 如何在不为每个资源编写单独的servlet来显示登录成功或被拒绝页面的情况下生成通用代码
  • 另外,有没有办法在shiro中为每个资源创建自定义权限?如果是的话,那怎么办。如果与此有任何联系,我将不胜感激


    谢谢大家。

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

    如果坚持使用servlet,则需要在会话中添加一个值,或将其作为参数添加到login.jsp请求中,该请求告诉它在成功身份验证后应将用户重定向到何处,并在用户身份验证后读取该参数


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

    我正在努力理解您的意思。好的,我会并且只想使用内置的shiro过滤器,但是在这种情况下,login.jsp中的action属性应该是什么,或者如何实现?我正在努力想办法。。。稍后,我必须使用JDBC领域
    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