2

I am trying to deploy my spring boot with angular 2 code to a war package

My springboot code contains JWT Spring security,

  1. The problem is when I integrate and run in tomcat server. I am getting:

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Mar 01 18:26:53 IST 2018 There was an unexpected error (type=Not Found, status=404). No message available

  1. But if i remove my spring security and integrate both together then it is working fine.

I don't know what is the problem with spring JWT security, So please, if anybody knows this issue, help me out

Web Security:

package com.boot.hms.security;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@CrossOrigin
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
    private UserDetailsService userDetailsService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public WebSecurity(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

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

        AuthenticationFilter authenticationFilter = new AuthenticationFilter(authenticationManager());
        authenticationFilter.setFilterProcessesUrl("/hms/auth");

        http .cors().and().csrf().disable().authorizeRequests().antMatchers("/hms/fetchmeta/*", "/hms/registration/*").permitAll()
        .anyRequest().authenticated().and().addFilter(authenticationFilter)
                .addFilter(new AuthorizationFilter(authenticationManager()))
                // this disables session creation on Spring Security
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);


        System.out.println("<....Web Security......>");
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    }   

    @Bean
        CorsConfigurationSource corsConfigurationSource() {
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
            return source;
        } 

}

POM XML:

<?xml version="1.0" encoding="UTF-8"?>
<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>
    <groupId>com.boot</groupId>
    <artifactId>hms</artifactId>
    <version>1</version>
    <packaging>war</packaging>

    <name>version</name>

    <description>Hospital Management System</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
        <relativePath/> 
    </parent>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <start-class>com.programmer.gate.HmsApplication</start-class>
    </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-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>         
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                  <webResources>
                    <resource>
                      <directory>D:\hmsDeployment\dist</directory>
                    </resource>
                  </webResources>
                </configuration>
              </plugin>

        </plugins>
    </build>


</project>

Main class:

package com.boot.hms;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.boot.hms.security.WebSecurity;

@CrossOrigin
@Import(WebSecurity.class)
@SpringBootApplication
@ComponentScan(basePackages="com.boot.hms")
public class HmsApplication extends SpringBootServletInitializer {

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

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

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }   

}

Property file:

#Database
spring.datasource.url= jdbc:mysql://192.168.12.112:3306/hms
spring.datasource.username=root
spring.datasource.password=root

#Server
#server.contextPath=/hms
#server.port = 8080
#JPA
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.autoconfigure.exclude=SecurityAutoConfiguration
#security.user.name=admin
#security.user.password=admin
security.basic.enabled=false
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
spring.jackson.deserialization.accept-empty-string-as-null-object=true
1
  • @lealceldeiro Hi, see now i am actually getting error like this:::::::::: Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Fri Mar 02 13:38:44 IST 2018 There was an unexpected error (type=Forbidden, status=403). Access Denied Commented Mar 2, 2018 at 8:47

1 Answer 1

1

Solution

You are probably seeing this error because of your custom security configuration class (WebSecurity)

You did not explicitly declared a "Free for all" rule for the base url, / (were the Angular app will live!). Here I am assuming the base url is /, if not adapt this answer to be used with your base real url.

So, in your WebSecurity add the mentioned rule by changing this:

 //...omitted code for brevity
 http.cors().and().csrf().disable().authorizeRequests()
    .antMatchers("/hms/fetchmeta/*", "/hms/registration/*").permitAll()
//...omitted code for brevity

to

 //...omitted code for brevity
 http.cors().and().csrf().disable().authorizeRequests()
    .antMatchers("/hms/fetchmeta/*", "/hms/registration/*", "/") // <--Notice here the base url added to the "free for all" rule!
    .permitAll()
//...omitted code for brevity

But ... Why this error happen?!

Well, as you commented, the explicit error is

Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Fri Mar 02 13:38:44 IST 2018 There was an unexpected error (type=Forbidden, status=403). Access Denied

This mean when you try to access the Angular app (located from the server point of view at the base url, /, for instance), the server detect that you're not logged in, so it throws a 403 Forbidden. This would normally be shown in an error page in a Spring Boot application... and since you do not have a mapping for this route, /error, (neither you have the file under src/main/resources/static/error/403.html which would normally show this error), then you see this "fallback" message you showed me.

Recommendation

Since now the base url / is free for all, your services (provided by Spring Boot) should be prefixed with something like /api or any similar in order to prevent free access to them.

Reference

If you want to have a reference, check this Security Config, which does exactly what you're trying to do (it belongs to a project which deploy a Spring Boot + Angular packed as war project)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much for your clarification, I am doing this deployment for more than a week. This is really helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.