How to setup pre-authentication header-based authentication in Spring Boot?
Asked Answered
P

1

15

My app gets an AUTH_USER request header with username from Oracle Access Manager SSO. Spring Security "Additional Topics" 2.2.1 has an example of "PreAuth" that seems to be what I need, but not a full working example.

Snippets below are from docs/examples, not working annotation-based configuration.

Siteminder Example Configuration - using XML with a RequestHeaderAuthenticationFilter and PreAuthenticatedAuthenticationProvider and a UserDetailsService to lookup users.

How does this map to Java-based config?

<security:http>
  <!-- Additional http configuration omitted -->
  <security:custom-filter position="PRE_AUTH_FILTER" ref="siteminderFilter" />
</security:http>

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

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

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

The Spring Security preauth example has a completely different setup (the XML config is even more intimidating). No mention of the pre-auth filter or how to set the header name.

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/login","/resources/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .jee()
                .mappableRoles("USER","ADMIN");
    }
}

The spring-boot-sample-web-secure extends WebMvcConfigurerAdapter instead of WebSecurityConfigurerAdapter, and just does basic form-based logins, no info on how to get userid from pre-auth AUTH_USER header.

public class SampleWebSecureApplication extends WebMvcConfigurerAdapter {

... omitted...

    @Bean
    public ApplicationSecurity applicationSecurity() {
        return new ApplicationSecurity();
    }

    @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
    protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

        @Autowired
        private SecurityProperties security;

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().fullyAuthenticated().and().formLogin()
                    .loginPage("/login").failureUrl("/login?error").permitAll();
        }
    }

}

I've read many references/articles but they do not seem to related to current code and Spring-boot, so stuck trying to understand how to configure the app pre-auth security.

Pastel answered 27/9, 2014 at 1:2 Comment(14)
Explaining what behavior you are seeing would help a lot. That said, your description says you're getting AUTH_USER, but principalRequestHeaderis set to "SM_USER".Classy
Thanks, Devon. The behavior is that I cannot get Spring config via annotations to even succeed. The above are code snippets from the examples. The variations make it difficult to be sure what I should even be creating: ie. WebSecurytConfigurerAdapter or WebMvcConfigurerAdpater? When I try to configure a RequestHeaderAuthenticationFilter, it requires several nested beans like AuthenticationManager and AuthProvider and DetailsService, but the HttpSecurity http object also has methods to set the authprovider and details service, but of slightly different types.Pastel
Just watched Spring Security 3.2 Webinar which helped a lot in understanding some of the annotations and configurations. Next up, I'm going to read the entire Spring Security ReferencePastel
@Tim: Hello Time,did you figure it out or do you still need help on this ? If you already figured it out, then it would be nice if you could post the answer. Thanks !Amberjack
@Pavan - No, have been on other topics, and have not figured this out yet. Please up-vote it if you're interested! :-)Pastel
@Tim: I have created a working model. Pls look at my answer :)Amberjack
@Amberjack - cool...where? (I don't see an answer here.)Pastel
@Tim: Can you now ? Anyways here is the URL github.com/sallampalli/codewiki/tree/master/…Amberjack
@Amberjack - I do not see an answer here on SO, but I'll check out Github. Thanks for sharing!Pastel
Hi @Amberjack - I can package springboot-security-preauth, but first error was incorrect start-class, after changing to com.codewiki.springpreauth.config.Application, app runs... but fails to inject a missing UserDetailsService dependency into WebSecurityConfiguration. I'll create one, and see if I can get further, but would be great to discuss live. Email me. :-)Pastel
Hey @Pastel - The UserDetailsServiceImpl class is the one that I put in there which implements the UserDetailsService provided by Spring. I see no reason that failing. Just make sure you have the right dependencies. Sure we can do that live. Thanks !Amberjack
@Amberjack - Sorry for the delay. I built and deployed as a Jar and as a War, but the server won't startup. Error traces back to: "No qualifying bean of type [com.codewiki.springpreauth.service.UserDetailsServiceImpl] found" -- even though I can see the UserDetailsServiceImpl class.Pastel
@Tim: Hey, sorry for responding late but just add this in your Application.java and you will be fine @ComponentScan(basePackages={"com.codewiki.springpreauth"})Amberjack
@Amberjack - (delay due to holiday, sorry) Great catch on the component scan! That and a few minor tweaks made it run with the embedded Tomcat Jar (added dependency for tomcat-embed-jasper in POM, fixed logout link, and deleted sessions on logout). You should submit the link to the code as your answer and I'll mark it correct. :-)Pastel
D
3

This is my way to configure pre-auth security based on injected userService:

@Configuration
@EnableWebSecurity
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true, securedEnabled = true, prePostEnabled = true, proxyTargetClass = true)
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    private static final Logger LOG = Logger.getLogger(ApplicationSecurity.class.getName());

    @Autowired
    private UserService userService; // implements AuthenticationUserDetailsService...

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        LOG.info("configure autentication provider with custom userService");
        PreAuthenticatedAuthenticationProvider paaProvider = new PreAuthenticatedAuthenticationProvider();
        paaProvider.setPreAuthenticatedUserDetailsService(userService);
        auth.authenticationProvider(paaProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        LOG.info("configure autentication filter");
        // ...
    }

}
Doubler answered 13/8, 2015 at 0:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.