How can Spring Security validate a AD user whose Authentication Provider is configured on WebLogic?

220 views Asked by At

Use-case:

I have a Spring Boot application v2.7.x. For the security, i am trying to configure a SecurityFilterChain that will point to an authentication provider (LDAP) that is configured in WebLogic v14.x.x.

The WebLogic configuration for the LDAP has been done here:

Security Realms > myrealm > Providers > Authentication tab

Question:

How do i point the Spring Boot Application to use that WebLogic Authentication Provider i.e the Spring Security configuration. Probably, something like here under LDAP Authentication section?


As a side-note, I will probably be needing these:

pom.xml
<dependency>
    <groupId>com.oracle.weblogic</groupId>
    <artifactId>weblogic-server-pom</artifactId>
    <version>12.2.1.4</version> <!-- Use the appropriate version for your WebLogic installation -->
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.oracle.weblogic</groupId>
    <artifactId>wlthint3client</artifactId>
    <version>12.2.1.4</version> <!-- Use the appropriate version for your WebLogic installation -->
    <scope>provided</scope>
</dependency>

weblogic.xml
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">
    <security-role-assignment>
        <role-name>authenticated-users</role-name>
        <principal-name>users</principal-name> 
    </security-role-assignment>
</weblogic-web-app>

Note:

I do not want to use an ActiveDirectoryLdapAuthenticationProvider that is pointing directly to the AD.

The final answer would probably be an extension of these 2 SO posts, this and this.

Authentication Provider (LDAP) configured in WebLogic:

enter image description here

1

There are 1 answers

2
httPants On BEST ANSWER

I have a spring boot application deployed in weblogic 12.2.1.4 that uses weblogic authentication. I have it configured as below...

src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

  <context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>default</param-value>
  </context-param>
  
  <login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
      <form-login-page>/login</form-login-page>
      <form-error-page>/login</form-error-page>
    </form-login-config>
  </login-config>

  <security-role>
    <role-name>USER</role-name>
  </security-role>
  
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Jobs</web-resource-name>
      <url-pattern>/jobs/*</url-pattern>
    </web-resource-collection>
    <web-resource-collection>
      <web-resource-name>Executions</web-resource-name>
      <url-pattern>/executions/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>USER</role-name>
    </auth-constraint>
    <user-data-constraint>
      <description>This is how the user data must be transmitted</description>
      <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
  </security-constraint>

</web-app>

src/main/webapp/WEB-INF/weblogic.xml

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
  <context-root>cmx-customer-file-faker</context-root>
  <container-descriptor>
    <prefer-application-packages>
      <package-name>org.slf4j.*</package-name>
      <package-name>org.springframework.*</package-name>
      <package-name>com.fasterxml.jackson.*</package-name>
    </prefer-application-packages>

    <prefer-application-resources>
      <resource-name>org/slf4j/impl/StaticLoggerBinder.class</resource-name>
    </prefer-application-resources>
  </container-descriptor>
  
  <security-role-assignment>
    <role-name>USER</role-name>
    <principal-name>users</principal-name>
  </security-role-assignment>
</weblogic-web-app>

WebSecurityConfig - this is where spring security is configured to use weblogic authentication via the J2eePreAuthenticatedProcessingFilter

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public MappableAttributesRetriever webXmlRolesParser() {
        return new WebXmlMappableAttributesRetriever();
    }

    @Bean
    public Attributes2GrantedAuthoritiesMapper roles2GrantedAuthoritiesMapper() {
        SimpleAttributes2GrantedAuthoritiesMapper var = new SimpleAttributes2GrantedAuthoritiesMapper();
        var.setAttributePrefix("");
        return var;
    }

    @Bean
    public J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource authenticationDetailsSource() {
        J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource var = new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
        var.setMappableRolesRetriever(webXmlRolesParser());
        var.setUserRoles2GrantedAuthoritiesMapper(roles2GrantedAuthoritiesMapper());
        return var;
    }

    @Bean
    public AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> getUserDetailsService() {
        return new PreAuthenticatedGrantedAuthoritiesUserDetailsService();
    }

    @Bean
    public AuthenticationProvider preAuthenticatedAuthenticationProvider() {
        PreAuthenticatedAuthenticationProvider var = new PreAuthenticatedAuthenticationProvider();
        var.setPreAuthenticatedUserDetailsService(getUserDetailsService());
        return var;
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Arrays.asList(preAuthenticatedAuthenticationProvider()));
    }

    @Bean
    public J2eePreAuthenticatedProcessingFilter j2eePreAuthFilter() {
        J2eePreAuthenticatedProcessingFilter var = new J2eePreAuthenticatedProcessingFilter();
        var.setAuthenticationDetailsSource(authenticationDetailsSource());
        var.setAuthenticationManager(authenticationManager());
        return var;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterAfter(j2eePreAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class)
                .authorizeRequests()
                .anyRequest()
                .permitAll()
                .and()
                .logout().logoutSuccessUrl("/bye")
                .and()
                .csrf().disable();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/webjars/**", "/login");
        super.configure(web);
    }

}

LoginController

@Controller
public class LoginController {

    @RequestMapping("/login")
    public String getLoginForm(HttpServletRequest request, Model model) {
        return "login";
    }

    @GetMapping("/bye")
    public String logoutSuccess() {
        return "logout";
    }

}

login.ftlh - my freemarker template for the login page.

<#import "/spring.ftl" as spring />

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="<@spring.url '/webjars/bootstrap/5.1.3/css/bootstrap.min.css'/>"/>
    <link rel="stylesheet" href="<@spring.url '/webjars/font-awesome/5.15.4/css/all.min.css'/>"/>
    
    <style>
    .fas.btn {
        font-weight: 900;
    }
    </style>

</head>  
<body>  
    <nav class="navbar navbar-expand-lg navbar-light" style="background-color: rgb(248, 249, 250)">
      <div class="container">
        <a class="navbar-brand" href="<@spring.url '/'/>">Login</a>
      </div>
    </nav>  
    
    <div class="mt-5 container">
        <div class="row justify-content-center">
            <div class="col-8">
                <#if Request['javax.servlet.error.message']??>
                <div class="alert alert-danger alert-dismissible fade show mb-5" role="alert">
                    ${Request['javax.servlet.error.message']}
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
                </#if>
                <form class="card" method="POST" action="j_security_check">
                    <div class="card-header">
                        <h5>Enter your login details</h5>
                    </div>
                    <div class="card-body">
                        <div class="mb-3">
                            <label for="InputUserName" class="form-label">User Name</label>
                            <input name="j_username" class="form-control" id="InputUserName" aria-describedby="userNameHelp">
                        </div>
                        <div class="mb-3">
                            <label for="InputPassword" class="form-label">Password</label>
                            <input name="j_password" type="password" class="form-control" id="InputPassword">
                        </div>
                        <button type="submit" class="btn btn-primary">Login</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    
    <script src="<@spring.url '/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js'/>"></script>
</body>  
</html>

pom.xml spring boot dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>bootstrap</artifactId>
        <version>5.1.3</version>
    </dependency>
    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>font-awesome</artifactId>
        <version>5.15.4</version>
    </dependency>
    ...
</dependencies>