0

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

jumping_monkey
  • 5,941
  • 2
  • 43
  • 58

1 Answers1

0

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>
httPants
  • 1,832
  • 1
  • 11
  • 13
  • Thanks @httPants, i will try it tomorrow. By the way, how does your code/configuration point to a particular authentication provider (LDAP in my case) configured in WebLogic under `Security Realms > myrealm > Providers > Authentication tab` (I have updated my question to show what i mean). Or is it based on the order of the authentication providers? – jumping_monkey Jun 22 '23 at 14:42
  • 1
    weblogic will try each Authenticator in turn until a user is successfully authenticated. If you wanted to ensure the user was from the LDAP authenticator, then perhaps configure the role that only users from the LDAP authenticator would have as the principal name (ie. weblogic.xml security-role-assignment/principal-name) – httPants Jun 22 '23 at 23:00