Skip to content
Advertisement

Getting an exception when tried to implement Azure AD authentication and authorization in Spring Boot

I receive the following error:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChainProxySecurityConfigurer' parameter 1; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2WebSecurityConfiguration$OAuth2WebSecurityConfigurerAdapter': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.OAuth2ClientConfiguration$OAuth2ClientWebMvcSecurityConfiguration': Unsatisfied dependency expressed through method 'setClientRegistrationRepository' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientRegistrationRepositoryConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.security.oauth2.client-org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Client id must not be empty.

Even though I’ve provided the client ID in application.properties.

I followed the following link: https://learn.microsoft.com/en-us/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory

POM:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath />
    <!-- lookup parent from repository -->
</parent>
<groupId>com.mmm</groupId>
<artifactId>UserMgmt</artifactId>
<version>1.0.3</version>
<packaging>war</packaging>
<name>UserMgmt</name>
<description>User Management</description>
<!-- FIXME change it to the project's website -->
<!-- <url>http://www.example.com</url> -->
<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
        <scope>runtime</scope>
    </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-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
    </dependency>
        <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-dynamodb</artifactId>
        <version>1.11.956</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-lambda</artifactId>
        <version>1.11.207</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.janino</groupId>
        <artifactId>janino</artifactId>
        <version>2.6.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
    <dependency>     
        <groupId>com.google.code.gson</groupId>     
        <artifactId>gson</artifactId>     
        <version>2.8.6</version>     
        </dependency>   
        <dependency>
        <groupId>com.sun.mail</groupId>
        <artifactId>javax.mail</artifactId>
        <version>1.6.2</version>
    </dependency>
    
    <dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-active-directory-spring-boot-starter</artifactId>
    <version>2.1.6</version>
    </dependency>

<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>


</dependencies>
<build> 
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
        
    
    <pluginManagement>

        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
            </plugin>
                <plugin>
                <groupId>org.jboss.as.plugins</groupId>
                <artifactId>jboss-as-maven-plugin</artifactId>
                <version>7.9.Final</version>
                </plugin>
            
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.1</version>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
            </plugin>
            <plugin>
                <artifactId>maven-install-plugin</artifactId>
                <version>2.5.2</version>
            </plugin>
            <plugin>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8.2</version>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
</project>

MAIN:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@SpringBootApplication
public class UserApplication extends SpringBootServletInitializer {
private static final Logger LOG = 
LoggerFactory.getLogger(UserApplication.class.getName());


public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);

}

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder 
application) {
return application.sources(UserApplication.class);
}

@Configuration
public class DataSourceConfiguration {/*creds*/}

CONTROLLER

@RequestMapping(value = "/")
@PreAuthorize("hasRole('ROLE_group1')"+"|| hasRole('ROLE_group2')"+"|| 
hasRole('ROLE_group3')")

APPLICATION.PROPERTIES

azure.activedirectory.tenant-id=xxxxxxxxxxxxxxx
azure.activedirectory.client-id=xxxxxxxxxxxxxxx
azure.activedirectory.client-secret=xxxxxxxxxxxxxx
azure.activedirectory.user-group.allowed-groups=group1,group2,group3

I updated my POM with

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-active-directory-spring-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
    <version>2.4.5</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.4.5</version>
</dependency>

The new error after updating POM:

 ERROR org.springframework.boot.SpringApplication [main] Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChainProxySecurityConfigurer' parameter 1; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.azure.spring.aad.webapp.AADWebAppConfiguration$DefaultAADWebSecurityConfigurerAdapter': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.OAuth2ClientConfiguration$OAuth2ClientWebMvcSecurityConfiguration': Unsatisfied dependency expressed through method 'setAuthorizedClientRepository' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authorizedClientRepository' defined in class path resource [com/azure/spring/aad/webapp/AADWebAppConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository]: Factory method 'authorizedClientRepository' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/security/oauth2/client/OAuth2AuthorizedClientProvider

I’ve updated my POM, now it is building fine, but on login I’m getting AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: ’18da6914-……………………….’. I added the following redirect URI: localhost:8080, localhost:8080/login/oauth2/code.

As I’m completely new to this, I would be thankful for any help.

Advertisement

Answer

Your code looks correct. But as the error shows “nested exception is java.lang.IllegalStateException: Client id must not be empty.”, you need to check the application.properties again and make sure it’s correct.

And the sample needs three dependencies(spring-boot-starter-oauth2-client, spring-boot-starter-web, azure-spring-boot-starter-active-directory), you could try to update your pom with the newer version.

There is my code following the tutorial.

Main:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@SpringBootApplication
public class SpringBootSampleAdApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSampleAdApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder 
    application) {
        return application.sources(SpringBootSampleAdApplication.class);
    }

    @Configuration
    public class DataSourceConfiguration {/*creds*/}
}

Controller:

@RestController
public class HelloController {

    @PreAuthorize("hasRole('ROLE_pamela-group1')"+"|| hasRole('ROLE_pamela-group2')")
    @RequestMapping("/test")
    public String helloWorld() {
        return "Hello Users!";
    }
}

application.properties:

azure.activedirectory.tenant-id=xxxxx
azure.activedirectory.client-id=xxxxx
azure.activedirectory.client-secret=xxxxx
azure.activedirectory.user-group.allowed-groups=pamela-group1,pamela-group2

application.properties

Test result:

enter image description here

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement