1

私のウェブサイトにアクセスするための 2 つの方法がある方法を探しています。

1) form-login を使用して権限を取得し、Web サイトを使用できる必要があります。

2) 別の Web サイトにログインできるはずです。そこでトークンを使用してリンクを押すと、私の Web サイトにログインできるはずです。(私は両方の Web サイトを管理しており、同じデータベースを使用しています)

ステージ 1 が完了し、正常に動作し、ステージ 2 をこのhttps://stackoverflow.com/a/9919988/1915913に似たものにしました。これも機能しています。トークンを取得し、それを確認してログインすることができます.

しかし、私の問題は、同じリソースに対して、両方を同時に機能させるにはどうすればよいかということです。私は問題が何であるかを知っていると確信しています.カスタムフィルターを作成し、フォームログインフィルターを使用しようとしています. それはうまくいきませんが、できますか?または、この機能を取得できる他の方法はありますか?

これは、事前認証フィルターが引き継ぐように見える方法では機能せず、通常のログインを機能させることができず、プロジェクトの新しいページに移動するたびに事前認証フィルターを呼び出すようです。

これに使用するクラスはすべて非常に単純です。

私のセキュリティアプリコンテキスト:

<http pattern="/**" use-expressions="true" create-session="always">
        <intercept-url pattern="/login.jsp*" access="permitAll" />
        <intercept-url pattern="/**" access="denyAll" />
        <custom-filter position="PRE_AUTH_FILTER" ref="PreAuthenticatedProcessingFilter" />
        <form-login
                username-parameter="idnumber"
                password-parameter="password" login-processing-url="/processlogin"
                login-page='/login.jsp'
                authentication-failure-handler-ref="myAuthErrorHandler"
                authentication-success-handler-ref="mySuccessHandler"
                always-use-default-target='true'
                authentication-failure-url="/login.jsp?login_error=true"/>
        <logout logout-url="/logout/" logout-success-url="/login.jsp" delete-cookies="JSESSIONID"/>
        <session-management invalid-session-url="/">
            <concurrency-control expired-url="/" max-sessions="2" />
        </session-management>
    </http>

    <!-- form login -->
    <beans:bean id="mySuccessHandler" class="is.inna.rest.login.SuccessHandler"/>
    <beans:bean id="myAuthErrorHandler" class="is.inna.rest.login.AuthentificationListener"/>
    <beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    <beans:bean name="myUserDetailsService" class="is.inna.rest.login.LoginUserDetailService" />

    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="myUserDetailsService">
            <password-encoder ref="passwordEncoder" />
        </authentication-provider>
        <authentication-provider ref="preauthAuthProvider" />
    </authentication-manager>

     <!-- Pre auth -->
    <beans:bean id="userDetailsServiceWrapper"  class="is.inna.rest.login.AuthUserDetailService" />
    <beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <beans:property name="preAuthenticatedUserDetailsService" ref="userDetailsServiceWrapper"/>
    </beans:bean>
    <beans:bean id="PreAuthenticatedProcessingFilter" class="is.inna.rest.login.PreAuthenticatedProcessingFilter">
        <beans:property name="authenticationManager" ref="authenticationManager" />
    </beans:bean>

ユーザー詳細サービス

public class AuthUserDetailService implements AuthenticationUserDetailsService<Authentication> {

@Override
public UserDetails loadUserDetails(Authentication authentication) throws UsernameNotFoundException {
    String id = (String) authentication.getPrincipal();
    NotandiHelper notandi = UserDAO.getNotandiByToken(id);

    return new User(notandi.getUsername(), notandi.getPassword(), notandi.getAuthorities());
}

}

私の事前認証フィルター

 public class PreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {

@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
    if(request.getParameter("id") != null){
        return request.getParameter("id");
    }else if(request.getParameter("idnumber") != null){
        return request.getParameter("idnumber");
    }
    return null;
}

@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
    if(request.getParameter("kt") != null){
        String[] credentials = new String[2];
        credentials[0] = request.getParameter("token");
        credentials[2] = request.getParameter("id");
        return credentials;
    }
    if(request.getParameter("idnumber")!= null){
        String[] credentials = new String[2];
        credentials[0] = request.getParameter("idnumber");
        credentials[1] = request.getParameter("password");
        return credentials;
    }

    return null;
}
4

1 に答える 1

1

クラスを拡張するときは、基本クラスがどのように機能するかを理解する必要があります (継承の問題の 1 つです)。この場合、トークンが存在しない場合に「false」を返します。これは、オブジェクトを返すメソッドの任意の選択です。基本クラスを見ると、null 以外のプリンシパルをチェックしdoAuthenticate、値が null の場合はすぐに戻り、事前認証フィルターがそこになかったかのように、フィルター チェーンがすぐに続行されることがわかります。全て。それは正しくありません。代わりに null を返してみてください。

デバッグ ログには次のようなログ メッセージも含まれている必要があることに注意してください。

preAuthenticatedPrincipal = null、認証を試みています

構成からは、トークンを認証する方法も不明です。それを行うものはないようです。

認証されていないユーザーに対してログイン フォームを自動的に表示する場合は、フォーム ログインのエントリ ポイントを使用する必要があることに注意してください。はhttp403EntryPoint、403 コードですぐに戻ります。

于 2014-08-20T13:16:03.540 に答える