0

ユーザーがログインしているかどうかに関係なく、ユーザーに関する外部ソース情報を受け取るWebアプリフィルターで実行しています。これが私のフィルターです:

@Override
public void doFilter( ServletRequest request, ServletResponse response,
                      FilterChain chain ) throws IOException, ServletException
{
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    String loginBean = httpRequest.getHeader( CommonVariables.LOGIN_BEAN );
    if ( loginBean == null )
    {
        System.out.println( "FILTER-----------" );
        try
        {
            String login;
            String domain;
            //Here i'm getting login and domain string
            loginBean = domain + "\\" + login;
            httpResponse.addHeader( "LoginBean", loginBean );
            System.out.println( login + " " + domain );
        } catch ( Exception e )
        {
            e.printStackTrace();
            //redirect to login page
            httpResponse.sendRedirect( "..." );
            return;
        }
    }
    chain.doFilter( request, response );
}

ただし、これらのヘッダーは次のフィルターに渡されます。したがって、SpringSecurityPRE_AUTH_FILTERを実装しました。

春のセキュリティコンテキスト

<http use-expressions="true" auto-config="false" entry-point-ref="http403EntryPoint">
    <!-- Additional http configuration omitted -->
    <custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</http>

<beans:bean id="siteminderFilter" class=
        "org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
    <beans:property name="principalRequestHeader" value="LoginBean"/>
    <beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>

<beans:bean id="preauthAuthProvider"
      class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <beans:property name="preAuthenticatedUserDetailsService">
        <beans:bean id="userDetailsServiceWrapper"
              class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
            <beans:property name="userDetailsService" ref="userDetailsService"/>
        </beans:bean>
    </beans:property>
</beans:bean>

<beans:bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
<beans:bean id="userDetailsService" class="com.execon.security.CustomUserDetailsService"/>

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="preauthAuthProvider" />
</authentication-manager>

次に、CustoUserDetailsS​​erviceでloginBean文字列を解析して、実際のユーザーオブジェクトを受信しようとしました。しかし、それは起動されず、アプリはこれで失敗します:

org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException: LoginBean header not found in request.

つまり、ヘッダーが間違って設定されているということですか?またはまったく設定されていませんか?何が悪いのでしょうか?

フィルタ設定LoginBeanが最初に起動され、次にSpringSECurityになります。私が持っているように、標準出力は問題なく動作します:

17:12:15,669 INFO  [stdout] (http--127.0.0.1-8080-2) FILTER-----------
17:12:15,669 INFO  [stdout] (http--127.0.0.1-8080-2) LOGIN DOMAIN
4

1 に答える 1

2

で何かを設定してresponseおり、Spring のクラスは で同じものを探していrequestます。

受信を変更できる唯一の方法HttpServletRequestは、それを装飾することです。最初に次のようにクラスを定義する必要があります。

public class AuthHttpServletRequest extends HttpServletRequestWrapper
{
    private String loginBean;

    public AuthHttpServletRequest(HttpServletRequest aRequest, String loginBean)
    {
        super(aRequest);
        this.loginBean = loginBean;
    }

    @Override
    public String getHeader(String headerName)
    {
        if(CommonVariables.LOGIN_BEAN.equals(headerName)) {
            return this.loginBean;
        }
        return super.getHeader(headerName);
    }
}

次に、フィルターの次の行を置き換えます。

httpResponse.addHeader( "LoginBean", loginBean );

これとともに:

request = new AuthHttpServletequest(httpRequest, loginBean);

次に、chain.doFilter意図したとおりに loginBean を返すことができるリクエストを、Spring の認証フィルター クラスに、フィルター チェーンの下位に取得します。

于 2012-09-23T15:24:28.300 に答える