8

Spring 3.2.0 と同じバージョンの Spring セキュリティを使用しています。ログインに成功すると、ユーザーは次のように保護されたページの 1 つにリダイレクトされます。

public final class LoginSuccessHandler implements AuthenticationSuccessHandler
{
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException
    {
        Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
        if (roles.contains("ROLE_ADMIN"))
        {
            response.sendRedirect("admin_side/Home.htm");
            return;
        }
    }
}

私は休止状態を使用しています。ログインが成功したときにデータベースのログイン日時 (最終ログイン) を更新するにはどうすればよいですか? ログインページに送信ボタンがありますが、そのPOSTリクエストは対応するログインコントローラーのメソッドにマップされていないようです。ログイン フォームのアクションは、実際にはサーブレットにマップされます - j_spring_security_check.


spring-security.xml必要に応じて、ファイル全体は次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <http pattern="/Login.htm*" security="none"></http>    

    <http auto-config='true'>
    <!--<remember-me key="myAppKey"/>-->
        <session-management session-fixation-protection="newSession">
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
        </session-management>

        <intercept-url pattern="/admin_side/**" access="ROLE_ADMIN" requires-channel="any"/>
        <form-login login-page="/" default-target-url="/admin_side/Home.htm" authentication-failure-url="/LoginFailed.htm" authentication-success-handler-ref="loginSuccessHandler"/>
        <logout logout-success-url="/Login.htm" invalidate-session="true" delete-cookies="JSESSIONID"/>
    </http>

    <authentication-manager>
       <authentication-provider>
            <jdbc-user-service data-source-ref="dataSource"
               users-by-username-query="select email_id, password, enabled from user_table where lower(email_id)=lower(?)"
               authorities-by-username-query="select ut.email_id, ur.authority from user_table ut, user_roles ur where ut.user_id=ur.user_id and lower(ut.email_id)=lower(?)"/>
       </authentication-provider>
    </authentication-manager>

    <beans:bean id="loginSuccessHandler" class="loginsuccesshandler.LoginSuccessHandler"/>

    <global-method-security>
        <protect-pointcut expression="execution(* dao.*.*(..))" access="ROLE_ADMIN"/>
    </global-method-security>

    <!--<global-method-security secured-annotations="enabled" />-->
</beans:beans>
4

3 に答える 3

23

もう 1 つの方法は、 のハンドラを登録することAuthenticationSuccessEventです。

    @Service
    public class UserService implements
                             ApplicationListener<AuthenticationSuccessEvent> {

        @Override
        public void onApplicationEvent(AuthenticationSuccessEvent event) {
           String userName = ((UserDetails) event.getAuthentication().
                                                  getPrincipal()).getUsername();
           User user = this.userDao.findByLogin(userName);
           user.setLastLoginDate(new Date());
        }
   }
于 2013-03-19T07:10:06.843 に答える
6

認証成功ハンドラーで直接実行しないのはなぜですか?

public final class LoginSuccessHandler implements AuthenticationSuccessHandler
{
    @Autowired
    private UserService userService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException
    {
        String userName = authentication.getPrincipal().getName();
        this.userService.updateLastLoginDateForUserByName(userName);

        Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
        if (roles.contains("ROLE_ADMIN"))
        {
            response.sendRedirect("admin_side/Home.htm");
            return;
        }
    }
}
于 2013-03-19T09:51:42.603 に答える
2

また、Spring インターフェイスをサブクラス化し、要素AuthenticationProviderに挿入することもできます。<authentication-manager />

クラスは次のようになります

public class AuthenticationProvider extends DaoAuthenticationProvider {

    // inject whatever tou want

    @Override
    public Authentication authenticate(Authentication authentication)
                throws AuthenticationException {
            return super.authenticate(authentication);

            // do what ever you want here
    }

}

(あなたが使用していると仮定DaoAuthenticationProvider

次に、Bean を登録するだけです。

<bean class="x.y.z.AuthenticationProvider" id="myAuthProvider" scope="singleton" />
<authentication-manager>
   <authentication-provider ref="myAuthProvider">
        <jdbc-user-service data-source-ref="dataSource"
           users-by-username-query="select email_id, password, enabled from user_table where lower(email_id)=lower(?)"
           authorities-by-username-query="select ut.email_id, ur.authority from user_table ut, user_roles ur where ut.user_id=ur.user_id and lower(ut.email_id)=lower(?)"/>
   </authentication-provider>
</authentication-manager>

(コードの正確性を信頼しないでください。私はその場で書いています。これは私の考えを示すためのものです。)

ステファノ

于 2013-03-19T15:44:28.277 に答える