2

We are migrating a Struts 1.3 web Application to SpringBoot. A feature of our application is to identify the Windows AD user and then call custom web services to authenticate, assign roles and automatically log into application.

In Struts, we used Waffle to identify the Windows AD logged in user by getting the value for request.getRemoteUser() in Java.

For Spring Boot, we have done the following

In pom.xml, we have added the dependencies

    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna</artifactId>
        <version>${jna.version}</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.jna</groupId>
        <artifactId>jna-platform</artifactId>
        <version>${jna.version}</version>
    </dependency>
    <dependency>
        <groupId>com.github.waffle</groupId>
        <artifactId>waffle-spring-security4</artifactId>
        <version>2.2.1</version>
    </dependency>

We have a SecurityConfig.java where we have made the following changes. Please note we are not using Spring based login.

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private NegotiateSecurityFilter negotiateSecurityFilter;

@Autowired
private NegotiateSecurityFilterEntryPoint entryPoint;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(negotiateSecurityFilter, BasicAuthenticationFilter.class);
    http.httpBasic().disable();
    http.csrf().disable().cors();
    }

@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication();

}
}

We have maintained the Waffle related configuration here - WaffleConfig.java

@Configuration
public class WaffleConfig {

        @Bean
        public WindowsAuthProviderImpl waffleWindowsAuthProvider() {
            return new WindowsAuthProviderImpl();
        }

        @Bean
        public NegotiateSecurityFilterProvider negotiateSecurityFilterProvider(
                WindowsAuthProviderImpl windowsAuthProvider) {
            return new NegotiateSecurityFilterProvider(windowsAuthProvider);
        }

        @Bean
        public BasicSecurityFilterProvider basicSecurityFilterProvider(WindowsAuthProviderImpl windowsAuthProvider) {
            return new BasicSecurityFilterProvider(windowsAuthProvider);
        }

        @Bean
        public SecurityFilterProviderCollection waffleSecurityFilterProviderCollection(
                NegotiateSecurityFilterProvider negotiateSecurityFilterProvider,
                BasicSecurityFilterProvider basicSecurityFilterProvider) {
            SecurityFilterProvider[] securityFilterProviders = {
                    negotiateSecurityFilterProvider,
                    basicSecurityFilterProvider };
            return new SecurityFilterProviderCollection(securityFilterProviders);
        }

        @Bean
        public NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint(
                SecurityFilterProviderCollection securityFilterProviderCollection) {
            NegotiateSecurityFilterEntryPoint negotiateSecurityFilterEntryPoint = new NegotiateSecurityFilterEntryPoint();
            negotiateSecurityFilterEntryPoint.setProvider(securityFilterProviderCollection);
            return negotiateSecurityFilterEntryPoint;
        }

        @Bean
        public NegotiateSecurityFilter waffleNegotiateSecurityFilter(SecurityFilterProviderCollection securityFilterProviderCollection) {
            NegotiateSecurityFilter negotiateSecurityFilter = new NegotiateSecurityFilter();
            negotiateSecurityFilter.setProvider(securityFilterProviderCollection);
            return negotiateSecurityFilter;
        }

        // This is required for Spring Boot so it does not register the same filter twice
        @Bean
        public FilterRegistrationBean waffleNegotiateSecurityFilterRegistration(NegotiateSecurityFilter waffleNegotiateSecurityFilter) {
            FilterRegistrationBean registrationBean = new FilterRegistrationBean();
            registrationBean.setFilter(waffleNegotiateSecurityFilter);
            registrationBean.setEnabled(false);
            return registrationBean;
        }
    }

However, when we try to get the value of request.getRemoteUser(), the value is null

What are we doing wrong for such a seemingly simple requirement?

user2739655
  • 141
  • 1
  • 3
  • 14

1 Answers1

2

I solved this by following the configurations here

https://github.com/Waffle/waffle/tree/master/Source/JNA/waffle-demo/waffle-spring-boot-filter2

In pom.xml, we have added the dependencies

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>${jna.version}</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>${jna.version}</version>
</dependency>
<dependency>
    <groupId>com.github.waffle</groupId>
    <artifactId>waffle-spring-boot-starter</artifactId>
    <version>2.2.1</version>
</dependency>

In the SecurityConfig.java the following changes

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private NegotiateSecurityFilter filter;
private NegotiateSecurityFilterEntryPoint entryPoint;

/**
 * Autowire constructor injects bean auto-configured by Starter.
 *
 * @param filter
 *            the filter
 * @param entryPoint
 *            the entry point
 */
public SecurityConfig(NegotiateSecurityFilter filter, NegotiateSecurityFilterEntryPoint entryPoint) {
    this.filter = filter;
    this.entryPoint = entryPoint;
}

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests().anyRequest().authenticated().and()
    .addFilterBefore(filter, BasicAuthenticationFilter.class).exceptionHandling()
    .authenticationEntryPoint(entryPoint);
}
}
user2739655
  • 141
  • 1
  • 3
  • 14