0

私は現在Struts2を学習しており、ログイン試行カウンターを作成して、x回の試行が失敗した後のそれ以上のログイン試行をブロックしようとしています。

これが私のlogin.jspの本文です

<body>

<h1><s:property value="loginAttempts"/></h1>

<s:form action="login">
    <s:textfield name="username" label="Username" />
    <s:password name="password" label="Password"/>
<%-- <s:hidden name="loginAttempts"  value="<s:property value="loginAttempts"/>" /> --%>
    <s:set var="loginAttempts"><s:property value="loginAttempts"/></s:set>
    <s:submit value="login"/>
</s:form>

</body>

そして私のアクションクラス(私はそれらのゲッターとセッターを含むプライベート変数を含めていませんが、それらはすべてそこにあります)

public String execute() throws Exception{

    if (username.equals("admin")&& password.equals("admin"))
    {   return SUCCESS;}
    else if (Integer.parseInt(getLoginAttempts())>2)
    {
        return "lockout";
    }
    else
    {   setLoginAttempts(String.valueOf(Integer.parseInt(getLoginAttempts())+1));
        return "fail";}
}

最初にlogin.jspを呼び出すアクションで、初期値を渡します

loginAttempts="0";

そしてそれはうまくいきます。login.jspページで送信を押すと問題が発生します。

次のスタックトレースを取得します

java.lang.NumberFormatException: null 
java.lang.Integer.parseInt(Integer.java:417)
java.lang.Integer.parseInt(Integer.java:499)
com.struts.users.LoginAction.execute(LoginAction.java:17)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

17行目は

else if (Integer.parseInt(getLoginAttempts())>2)

そして、送信ボタンを押すたびに、loginAttempt変数は自動的ににリセットされNULLます。

ありがとう

Edit: I understand that this probably isn't the right way to be doing this and i should probably be doing this with sessions. However I am trying to understand why it isn't working.

4

1 に答える 1

0

A struts2 action is not persistent! It is recreated each and every time the request happens.
What you need to do is implement the ServletRequestAware interface for the action which will give you access to the HttpServletRequest, you can then obtian the http session object stored by your webserver and increment the value on that. Be careful as this will need to be threadsafe - you may need to lock the http session while updaing the value.
Another approach would be to have an object in the ServletContext that stored a Map of username to login attempts. This may be more reliable.

A bit of clarification from comments:

Your form sends (known as POSTing) the values on it to your webserver, struts2 then takes this 'POST data' and interprets it for you - using the relevant setters on your action to make this data available to you.
So, in order to send the login attempts value your form needs to have it as a variable, hence the need for an <s:hidden>. Your action should then have a setter for loginattempts; i.e. a method with the signature setLoginAttempts(int loginAttempts).
Now, when your action is done and finds that the request is invalid you want to increment that variable and provide a getter for it in the action.
Now your JSP, which is rendered by the action on a failed attempt, can read that value off the action and add it to the HTML form that the user will send. Hence my reference to a circle.
This method will not do anything to add to the security of your website as the variable loginAttempts is read from the user POST data - the user can send anything it wants and your action will read that as the number of login attempts.
I hope that helps...

于 2013-02-15T16:00:59.597 に答える