0

プロジェクトに役割ベースのメカニズムを作成する必要があるため、プロジェクトに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>

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

TOMCAT6.0を使用しています。

私の問題は-

  1. login.jspページでクレデンシャルを入力しようとすると、入力したクレデンシャルのそれぞれのページに自動的に移動します。たとえば、success.jspをクリックした後にROLE_MEMBERクレデンシャルを入力しようとすると、success.jspページに移動します。しかし、同じsuccess.jspをクリックした後にROLE_ADMINを入力しようとすると、denied.jspに移動する代わりに、記述されたサーブレットコードに従って自動的にsecret.jspに移動します。
  2. ログインの成功または拒否されたページを表示するために、リソースごとに個別のサーブレットを作成せずに汎用コードを作成するにはどうすればよいですか?

また、すべてのリソースに対してshiroでカスタム権限を作成する方法はありますか?はいの場合、その方法。これへのリンクがあれば、私はあなたに感謝します。

皆さんありがとう。

4

1 に答える 1

0

ガイドですでに定義されているように事前に構築されたフィルターを使用するのではなく、サーブレット内で認証を処理することにしたのはなぜだろうかと思います(とりわけ、構成を再ロードし、SecurityManagerリクエストごとに新しいものを作成しているようです...)。フィルタは、#1の詳細を処理する必要があります。

サーブレットの使用を主張する場合は、セッションに値を追加するか、login.jspのリクエストにパラメータとして値を追加する必要があります。これにより、認証が成功した後にユーザーをリダイレクトし、ユーザーが認証されたらそのパラメータを読み取る必要があります。 。

#2に関しては、success.jsp認証が成功した後に転送するだけです。1)ユーザーのロールを明示的にチェックしたり、フレームワークにチェックを許可したりすることはありません。繰り返しますが、フィルターに切り替えると、これが解決するはずです。

于 2011-11-08T21:51:24.020 に答える