Spring boot spring security options call 403










0















I'm using Spring Boot 2.x + Spring Security + JWT to create REST API for my Angular 5 application.



I can login using POSTMAN but from Angular application, my OPTIONS call fails:



Request URL: http://localhost:8080/api/v1/login
Request Method: OPTIONS
Status Code: 403
Remote Address: [::1]:8080


SecurityConfiguration.java



import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

@Autowired
private DataSource dataSource;

@Value("$spring.queries.users-query")
private String usersQuery;

@Value("$spring.queries.roles-query")
private String rolesQuery;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.jdbcAuthentication().usersByUsernameQuery(usersQuery).authoritiesByUsernameQuery(rolesQuery).dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);


@Override
protected void configure(HttpSecurity http) throws Exception
http.cors().disable().csrf().disable().authorizeRequests().antMatchers("/").permitAll().antMatchers("/").permitAll();


@Override
public void configure(WebSecurity web) throws Exception
web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");




application.properties



# ===============================
# = DATA SOURCE
# ===============================
spring.datasource.url=jdbc:mysql://localhost:3306/some_db

spring.datasource.username=some_user
spring.datasource.password=some_password
spring.datasource.driverClassName=com.mysql.jdbc.Driver

# ===============================
# = JPA / HIBERNATE SETTINGS
# ===============================

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto = validate

# =============================================================
# = Spring Security / Queries for AuthenticationManagerBuilder
# =============================================================

spring.queries.users-query=select email, password from users where email=?
spring.queries.roles-query=select u.email, r.role from users u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?

# ===========================
# = JSON WEB TOKEN SETTINGS
# ===========================

jwt.secret= JWTSuperSecretKey
jwt.expiration = 604800000


POSTMAN:



POST: http://localhost:8080/api/v1/login



Content-Type: application/x-www-form-urlencoded



Is it a header problem from angular side?










share|improve this question


























    0















    I'm using Spring Boot 2.x + Spring Security + JWT to create REST API for my Angular 5 application.



    I can login using POSTMAN but from Angular application, my OPTIONS call fails:



    Request URL: http://localhost:8080/api/v1/login
    Request Method: OPTIONS
    Status Code: 403
    Remote Address: [::1]:8080


    SecurityConfiguration.java



    import javax.sql.DataSource;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Configuration;
    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.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

    @Configuration
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private DataSource dataSource;

    @Value("$spring.queries.users-query")
    private String usersQuery;

    @Value("$spring.queries.roles-query")
    private String rolesQuery;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    auth.jdbcAuthentication().usersByUsernameQuery(usersQuery).authoritiesByUsernameQuery(rolesQuery).dataSource(dataSource)
    .passwordEncoder(bCryptPasswordEncoder);


    @Override
    protected void configure(HttpSecurity http) throws Exception
    http.cors().disable().csrf().disable().authorizeRequests().antMatchers("/").permitAll().antMatchers("/").permitAll();


    @Override
    public void configure(WebSecurity web) throws Exception
    web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");




    application.properties



    # ===============================
    # = DATA SOURCE
    # ===============================
    spring.datasource.url=jdbc:mysql://localhost:3306/some_db

    spring.datasource.username=some_user
    spring.datasource.password=some_password
    spring.datasource.driverClassName=com.mysql.jdbc.Driver

    # ===============================
    # = JPA / HIBERNATE SETTINGS
    # ===============================

    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto = validate

    # =============================================================
    # = Spring Security / Queries for AuthenticationManagerBuilder
    # =============================================================

    spring.queries.users-query=select email, password from users where email=?
    spring.queries.roles-query=select u.email, r.role from users u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?

    # ===========================
    # = JSON WEB TOKEN SETTINGS
    # ===========================

    jwt.secret= JWTSuperSecretKey
    jwt.expiration = 604800000


    POSTMAN:



    POST: http://localhost:8080/api/v1/login



    Content-Type: application/x-www-form-urlencoded



    Is it a header problem from angular side?










    share|improve this question
























      0












      0








      0








      I'm using Spring Boot 2.x + Spring Security + JWT to create REST API for my Angular 5 application.



      I can login using POSTMAN but from Angular application, my OPTIONS call fails:



      Request URL: http://localhost:8080/api/v1/login
      Request Method: OPTIONS
      Status Code: 403
      Remote Address: [::1]:8080


      SecurityConfiguration.java



      import javax.sql.DataSource;

      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Configuration;
      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.builders.WebSecurity;
      import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
      import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
      import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

      @Configuration
      @EnableWebSecurity
      public class SecurityConfiguration extends WebSecurityConfigurerAdapter
      @Autowired
      private BCryptPasswordEncoder bCryptPasswordEncoder;

      @Autowired
      private DataSource dataSource;

      @Value("$spring.queries.users-query")
      private String usersQuery;

      @Value("$spring.queries.roles-query")
      private String rolesQuery;

      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception
      auth.jdbcAuthentication().usersByUsernameQuery(usersQuery).authoritiesByUsernameQuery(rolesQuery).dataSource(dataSource)
      .passwordEncoder(bCryptPasswordEncoder);


      @Override
      protected void configure(HttpSecurity http) throws Exception
      http.cors().disable().csrf().disable().authorizeRequests().antMatchers("/").permitAll().antMatchers("/").permitAll();


      @Override
      public void configure(WebSecurity web) throws Exception
      web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");




      application.properties



      # ===============================
      # = DATA SOURCE
      # ===============================
      spring.datasource.url=jdbc:mysql://localhost:3306/some_db

      spring.datasource.username=some_user
      spring.datasource.password=some_password
      spring.datasource.driverClassName=com.mysql.jdbc.Driver

      # ===============================
      # = JPA / HIBERNATE SETTINGS
      # ===============================

      spring.jpa.show-sql=true
      spring.jpa.hibernate.ddl-auto = validate

      # =============================================================
      # = Spring Security / Queries for AuthenticationManagerBuilder
      # =============================================================

      spring.queries.users-query=select email, password from users where email=?
      spring.queries.roles-query=select u.email, r.role from users u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?

      # ===========================
      # = JSON WEB TOKEN SETTINGS
      # ===========================

      jwt.secret= JWTSuperSecretKey
      jwt.expiration = 604800000


      POSTMAN:



      POST: http://localhost:8080/api/v1/login



      Content-Type: application/x-www-form-urlencoded



      Is it a header problem from angular side?










      share|improve this question














      I'm using Spring Boot 2.x + Spring Security + JWT to create REST API for my Angular 5 application.



      I can login using POSTMAN but from Angular application, my OPTIONS call fails:



      Request URL: http://localhost:8080/api/v1/login
      Request Method: OPTIONS
      Status Code: 403
      Remote Address: [::1]:8080


      SecurityConfiguration.java



      import javax.sql.DataSource;

      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Configuration;
      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.builders.WebSecurity;
      import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
      import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
      import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

      @Configuration
      @EnableWebSecurity
      public class SecurityConfiguration extends WebSecurityConfigurerAdapter
      @Autowired
      private BCryptPasswordEncoder bCryptPasswordEncoder;

      @Autowired
      private DataSource dataSource;

      @Value("$spring.queries.users-query")
      private String usersQuery;

      @Value("$spring.queries.roles-query")
      private String rolesQuery;

      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception
      auth.jdbcAuthentication().usersByUsernameQuery(usersQuery).authoritiesByUsernameQuery(rolesQuery).dataSource(dataSource)
      .passwordEncoder(bCryptPasswordEncoder);


      @Override
      protected void configure(HttpSecurity http) throws Exception
      http.cors().disable().csrf().disable().authorizeRequests().antMatchers("/").permitAll().antMatchers("/").permitAll();


      @Override
      public void configure(WebSecurity web) throws Exception
      web.ignoring().antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/images/**");




      application.properties



      # ===============================
      # = DATA SOURCE
      # ===============================
      spring.datasource.url=jdbc:mysql://localhost:3306/some_db

      spring.datasource.username=some_user
      spring.datasource.password=some_password
      spring.datasource.driverClassName=com.mysql.jdbc.Driver

      # ===============================
      # = JPA / HIBERNATE SETTINGS
      # ===============================

      spring.jpa.show-sql=true
      spring.jpa.hibernate.ddl-auto = validate

      # =============================================================
      # = Spring Security / Queries for AuthenticationManagerBuilder
      # =============================================================

      spring.queries.users-query=select email, password from users where email=?
      spring.queries.roles-query=select u.email, r.role from users u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?

      # ===========================
      # = JSON WEB TOKEN SETTINGS
      # ===========================

      jwt.secret= JWTSuperSecretKey
      jwt.expiration = 604800000


      POSTMAN:



      POST: http://localhost:8080/api/v1/login



      Content-Type: application/x-www-form-urlencoded



      Is it a header problem from angular side?







      spring-boot spring-security angular5






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked May 5 '18 at 18:21









      AshutoshAshutosh

      1,33832554




      1,33832554






















          1 Answer
          1






          active

          oldest

          votes


















          0














          You disable CORS which means that your server will not tell the frontend to allow request to any origin but itself. By telling the server to accepting requests from another origin, e.g. localhost:4200 and the methods GET, PUT, POST, DELETE and OPTIONS your application should work.



          The following setup is a bit more complicated than it needs to be but it keeps things nice and tidy separated.



          The definition of the allowed origins should be put in the application.yml e.g.



          cors:
          allowed-origins:
          - https://localhost:4200
          - http://localhost:4200
          - http://127.0.0.1:4200
          - https://127.0.0.1:4200


          Then you add two files, one to load the config...



          @Configuration
          @ConfigurationProperties("cors")
          public class CorsConfig
          private List<String> allowedOrigins = new ArrayList<>();
          private String allowedMethods =
          HttpMethod.GET.name(),
          HttpMethod.HEAD.name(),
          HttpMethod.POST.name(),
          HttpMethod.PUT.name(),
          HttpMethod.DELETE.name()
          ;

          public List<String> getAllowedOrigins()
          return allowedOrigins;


          public String getAllowedOriginsArray()
          return getAllowedOrigins().toArray(new String[0]);


          public String getAllowedMethods()
          return allowedMethods;




          ... and one to put it to work.



          @Configuration
          @EnableWebMvc
          public class WebMvcConfig implements WebMvcConfigurer
          private final CorsConfig corsConfig;

          public WebMvcConfig(CorsConfig corsConfig)
          this.corsConfig = corsConfig;


          @Override
          public void addCorsMappings(CorsRegistry registry)
          registry.addMapping("/**")
          .allowedOrigins(corsConfig.getAllowedOriginsArray())
          .allowedMethods(corsConfig.getAllowedMethods());







          share|improve this answer






















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50192696%2fspring-boot-spring-security-options-call-403%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            You disable CORS which means that your server will not tell the frontend to allow request to any origin but itself. By telling the server to accepting requests from another origin, e.g. localhost:4200 and the methods GET, PUT, POST, DELETE and OPTIONS your application should work.



            The following setup is a bit more complicated than it needs to be but it keeps things nice and tidy separated.



            The definition of the allowed origins should be put in the application.yml e.g.



            cors:
            allowed-origins:
            - https://localhost:4200
            - http://localhost:4200
            - http://127.0.0.1:4200
            - https://127.0.0.1:4200


            Then you add two files, one to load the config...



            @Configuration
            @ConfigurationProperties("cors")
            public class CorsConfig
            private List<String> allowedOrigins = new ArrayList<>();
            private String allowedMethods =
            HttpMethod.GET.name(),
            HttpMethod.HEAD.name(),
            HttpMethod.POST.name(),
            HttpMethod.PUT.name(),
            HttpMethod.DELETE.name()
            ;

            public List<String> getAllowedOrigins()
            return allowedOrigins;


            public String getAllowedOriginsArray()
            return getAllowedOrigins().toArray(new String[0]);


            public String getAllowedMethods()
            return allowedMethods;




            ... and one to put it to work.



            @Configuration
            @EnableWebMvc
            public class WebMvcConfig implements WebMvcConfigurer
            private final CorsConfig corsConfig;

            public WebMvcConfig(CorsConfig corsConfig)
            this.corsConfig = corsConfig;


            @Override
            public void addCorsMappings(CorsRegistry registry)
            registry.addMapping("/**")
            .allowedOrigins(corsConfig.getAllowedOriginsArray())
            .allowedMethods(corsConfig.getAllowedMethods());







            share|improve this answer



























              0














              You disable CORS which means that your server will not tell the frontend to allow request to any origin but itself. By telling the server to accepting requests from another origin, e.g. localhost:4200 and the methods GET, PUT, POST, DELETE and OPTIONS your application should work.



              The following setup is a bit more complicated than it needs to be but it keeps things nice and tidy separated.



              The definition of the allowed origins should be put in the application.yml e.g.



              cors:
              allowed-origins:
              - https://localhost:4200
              - http://localhost:4200
              - http://127.0.0.1:4200
              - https://127.0.0.1:4200


              Then you add two files, one to load the config...



              @Configuration
              @ConfigurationProperties("cors")
              public class CorsConfig
              private List<String> allowedOrigins = new ArrayList<>();
              private String allowedMethods =
              HttpMethod.GET.name(),
              HttpMethod.HEAD.name(),
              HttpMethod.POST.name(),
              HttpMethod.PUT.name(),
              HttpMethod.DELETE.name()
              ;

              public List<String> getAllowedOrigins()
              return allowedOrigins;


              public String getAllowedOriginsArray()
              return getAllowedOrigins().toArray(new String[0]);


              public String getAllowedMethods()
              return allowedMethods;




              ... and one to put it to work.



              @Configuration
              @EnableWebMvc
              public class WebMvcConfig implements WebMvcConfigurer
              private final CorsConfig corsConfig;

              public WebMvcConfig(CorsConfig corsConfig)
              this.corsConfig = corsConfig;


              @Override
              public void addCorsMappings(CorsRegistry registry)
              registry.addMapping("/**")
              .allowedOrigins(corsConfig.getAllowedOriginsArray())
              .allowedMethods(corsConfig.getAllowedMethods());







              share|improve this answer

























                0












                0








                0







                You disable CORS which means that your server will not tell the frontend to allow request to any origin but itself. By telling the server to accepting requests from another origin, e.g. localhost:4200 and the methods GET, PUT, POST, DELETE and OPTIONS your application should work.



                The following setup is a bit more complicated than it needs to be but it keeps things nice and tidy separated.



                The definition of the allowed origins should be put in the application.yml e.g.



                cors:
                allowed-origins:
                - https://localhost:4200
                - http://localhost:4200
                - http://127.0.0.1:4200
                - https://127.0.0.1:4200


                Then you add two files, one to load the config...



                @Configuration
                @ConfigurationProperties("cors")
                public class CorsConfig
                private List<String> allowedOrigins = new ArrayList<>();
                private String allowedMethods =
                HttpMethod.GET.name(),
                HttpMethod.HEAD.name(),
                HttpMethod.POST.name(),
                HttpMethod.PUT.name(),
                HttpMethod.DELETE.name()
                ;

                public List<String> getAllowedOrigins()
                return allowedOrigins;


                public String getAllowedOriginsArray()
                return getAllowedOrigins().toArray(new String[0]);


                public String getAllowedMethods()
                return allowedMethods;




                ... and one to put it to work.



                @Configuration
                @EnableWebMvc
                public class WebMvcConfig implements WebMvcConfigurer
                private final CorsConfig corsConfig;

                public WebMvcConfig(CorsConfig corsConfig)
                this.corsConfig = corsConfig;


                @Override
                public void addCorsMappings(CorsRegistry registry)
                registry.addMapping("/**")
                .allowedOrigins(corsConfig.getAllowedOriginsArray())
                .allowedMethods(corsConfig.getAllowedMethods());







                share|improve this answer













                You disable CORS which means that your server will not tell the frontend to allow request to any origin but itself. By telling the server to accepting requests from another origin, e.g. localhost:4200 and the methods GET, PUT, POST, DELETE and OPTIONS your application should work.



                The following setup is a bit more complicated than it needs to be but it keeps things nice and tidy separated.



                The definition of the allowed origins should be put in the application.yml e.g.



                cors:
                allowed-origins:
                - https://localhost:4200
                - http://localhost:4200
                - http://127.0.0.1:4200
                - https://127.0.0.1:4200


                Then you add two files, one to load the config...



                @Configuration
                @ConfigurationProperties("cors")
                public class CorsConfig
                private List<String> allowedOrigins = new ArrayList<>();
                private String allowedMethods =
                HttpMethod.GET.name(),
                HttpMethod.HEAD.name(),
                HttpMethod.POST.name(),
                HttpMethod.PUT.name(),
                HttpMethod.DELETE.name()
                ;

                public List<String> getAllowedOrigins()
                return allowedOrigins;


                public String getAllowedOriginsArray()
                return getAllowedOrigins().toArray(new String[0]);


                public String getAllowedMethods()
                return allowedMethods;




                ... and one to put it to work.



                @Configuration
                @EnableWebMvc
                public class WebMvcConfig implements WebMvcConfigurer
                private final CorsConfig corsConfig;

                public WebMvcConfig(CorsConfig corsConfig)
                this.corsConfig = corsConfig;


                @Override
                public void addCorsMappings(CorsRegistry registry)
                registry.addMapping("/**")
                .allowedOrigins(corsConfig.getAllowedOriginsArray())
                .allowedMethods(corsConfig.getAllowedMethods());








                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 15 '18 at 10:19









                Christoph Grimmer-DietrichChristoph Grimmer-Dietrich

                2,48733052




                2,48733052





























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f50192696%2fspring-boot-spring-security-options-call-403%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    這個網誌中的熱門文章

                    How to read a connectionString WITH PROVIDER in .NET Core?

                    Node.js Script on GitHub Pages or Amazon S3

                    Museum of Modern and Contemporary Art of Trento and Rovereto