I’m running in my web app filter, which recieves from external source info about user, if he’s logged in or not. Heres my filter:
@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 );
}
Not I though that those header will be passed into next filters. Therefore I implemented Spring Security PRE_AUTH_FILTER:
Spring security context
<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>
Then I tried to parse loginBean String in my CustoUserDetailsService and receive actuall user object. But It is not fired, and app fails with this:
org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException: LoginBean header not found in request.
So that means the header is set wrong? Or not set at all? What might be wrong?
Filter setting LoginBean is first one fired, then goes Spring SEcurity. Standard output works ok as I have:
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
You are setting something in the
responseand the Spring’s class is looking for the same in therequest.The only way you can modify an incoming
HttpServletRequestis to decorate it. You should define a class as follows first:Then, replace the following line in your filter:
with this:
Then your
chain.doFiltergets the request that can return the loginBean as you intended it to, to the Spring’s authentication filter class, down in the filter chain.