#StackBounty: #spring-boot #spring-security-oauth2 #spring-oauth2 #spring-security-rest How to validate facebook authorization token an…

Bounty: 50

I am developing an app whose frontend is written using React.js and the backend REST API is written using the Spring framework. I wanted to add social logins to my website, so after days of googling and research, I understood that OAuth2 is the solution. I came to know that the frontend should handle getting the authorization token from the Resource Server(Facebook here) and my backend(java) should validate that token and connect with Facebook to get an access token. Then that access token should be stored in my database along with the user details(e.g email).

Here is my requirement, once the user clicks on the “Continue with Facebook” button, my app should create there account in my own database using details – email and Name(the signup feature). And later whenever they click on this button again, they will be logged in not sign up. The way other websites handle it.

As of now, I have the button working in my app, which brings me the authorization token from Facebook.

Can someone please guide me the path I should follow here.

Also, any special attention to some error handling I should follow.


Get this bounty!!!

#StackBounty: #spring #spring-boot #spring-security #jwt #spring-security-oauth2 OAuth2 + Spring Boot 2 – ResourceServer in ZuulGateway…

Bounty: 50

I am trying OAuth 2 + JWT integration using Spring Boot 2 + Netflix OSS. On requesting access token, I am getting the below error in Zuul Gateway which acts as a Resource Server.

2019-05-04 14:41:29.157 DEBUG 23272 — [nio-8765-exec-2] o.s.s.w.a.ExceptionTranslationFilter : Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

Can someone help and tell me what am I missing in the code ?

Zuul Gateway + Resource Server

@Configuration
@EnableResourceServer
@Order(value = 0)
@EnableOAuth2Sso
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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

        http.authorizeRequests()
            .antMatchers("/oauth/token/**").permitAll()
            //.antMatchers("/login/**,/oauth/**").permitAll()
            .antMatchers("/trips/**").hasAnyRole("CLIENT", "USER", "ANONYMOUS")
            .and().csrf().disable()
            .anonymous().disable();

    }
}

application.yml

logging:
  level:
    org.springframework: DEBUG

server:
  port: 8765

spring:
  application:
    name: gateway


# Map path to auth service
zuul:
  routes:
    trips:
      path: /trips/**
      url: http://localhost:1000/api/trips
    rides:
      path: /rides/**
      url: http://localhost:1000/api/rides
    mauth:
      path: /oauth/**
      url: http://localhost:1000/oauth



#OAuth Configurations
security:
  oauth2:
    client:
      #access-token-uri: https://auth/login
      #user-authorization-uri: /auth/oauth/authorize
      accessTokenUri: http://localhost:1000/oauth/authorize
      userAuthorizationUri: http://localhost:1000/oauth/token
      client-id: sapepool
      client-secret: sapepool
    resource:
      jwt:
        key-uri: http://localhost:1000/oauth/token_key
        #key-value:

Authorization Server

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

        @Autowired
        @Qualifier("authenticationManagerBean")
        private AuthenticationManager authenticationManager;

        @Autowired
        @Qualifier("customUserDetailsService")
        private UserDetailsService userDetailsService;

        /**
         * Token store.
         *
         * @return the token store
         */
        /*@Bean
        public DatastoreTokenStore tokenStore() {
            return new DatastoreTokenStore(datastoreDataSource);
        }*/
        @Bean
        public TokenStore tokenStore() {
            return new JwtTokenStore(jwtAccessTokenConverter());
        }

        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setKeyPair(new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "password".toCharArray()).getKeyPair("jwt"));
            converter.setSigningKey("123");
            converter.setVerifierKey("123");
            return converter;
        }

        /**
         * 
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

            endpoints.authenticationManager(authenticationManager).userDetailsService(userDetailsService)
                    .tokenStore(tokenStore())//.tokenServices(tokenServices())
                    .tokenEnhancer(jwtAccessTokenConverter())
                    .accessTokenConverter(jwtAccessTokenConverter())
                    .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
        }

         /**
         * Authorization server security Configuration.
         *
         * @param oauthServer
         *            the oauth server
         * @throws Exception
         *             the exception
         */
        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                .withClient("sapepool")
                .secret("{noop}sapepool")
                //.secret("sapepool")
                .authorizedGrantTypes("client_credentials", "password","refresh_token")
                .authorities("ROLE_CLIENT", "ROLE_ANDROID_CLIENT", "ROLE_ANONYMOUS")
                .scopes("read", "write", "trust")
                .accessTokenValiditySeconds(5000)
                .refreshTokenValiditySeconds(50000);
                //.resourceIds("oauth2-resource") - isAutoApprove()
        }
    }

Authorization Server – Web Security Config

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static Logger log = LoggerFactory.getLogger(WebSecurityConfig.class);


    @Autowired
    private UserDetailsService userDetailsService;


    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

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

        http.authorizeRequests()
            .antMatchers("/oauth/token/**").permitAll()
            .anyRequest().permitAll()
            //.antMatchers("*/oauth/**").permitAll()
            //.antMatchers("/**").permitAll()
            .and().csrf().disable();
            //.anonymous().disable();

        /*
         * http.csrf().disable().exceptionHandling() //.authenticationEntryPoint( //
         * (request, response, authException) ->
         * response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
         * .and().authorizeRequests().antMatchers("/**").authenticated().and().httpBasic
         * ();
         */
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

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


Get this bounty!!!

#StackBounty: #java #spring-boot #heroku #oauth-2.0 How do I stop Heroku from changing the location header and causing 401 with my Spri…

Bounty: 150

I have a spring boot oauth2 service working locally. But when I deploy this to Heroku it fails with a 401.

So on my local system I go to the UI and I have no valid JWT so it does a redirect to:

localhost:8080/api/auth/oauth/authorize?response_type=token&client_id=clienteagleeye&redirect_uri=http%3A%2F%2Flocalhost%3A4200&scope=webClient

The spring gateway routes to my auth service, localhost:8066/auth/login. I login with valid username/password and it routes to localhost:8066/auth/validate, which gives this response header:

Location: localhost:8066/auth/oauth/authorize?response_type=token&client_id=clienteagleeye&redirect_uri=http%3A%2F%2Flocalhost%3A4200&scope=webClient

It redirects to:

localhost:8066/auth/oauth/authorize?response_type=token&client_id=clienteagleeye&redirect_uri=http%3A%2F%2Flocalhost%3A4200&scope=webClient

…and the response header location on that call is: localhost:4200#access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.etc...

It routes back to the UI and I have the access token. Everything works as expected.

I do this in Heroku I get to this auth/validate step abc-authserver.herokuapp.com/auth/validate, and the response header location is Location: abc-authserver.herokuapp.com/auth/.

I am expecting it to be:

abc-authserver.herokuapp.com/auth/oauth/authorize?response_type=token&client_id=clienteagleeye&redirect_uri=https%3A%2F%dummyui&scope=webClient

but its not so it routes to abc-authserver.herokuapp.com/auth/ and I get a 401.

Why is Heroku dropping my response_type, client_id, scope and redirect_uri information? Why is it changing the Location in the response header when I am validating? The logs show that my username and password are correct and I have the information. It just has no idea where to go.

This is my resourceConfig in the authservice…

@Configuration
@EnableConfigurationProperties
public class ResourceConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .cors().and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.NEVER).and()
            .authorizeRequests()
            .antMatchers("/api/**", "/auth/**", "/oauth/**", "/login", "/validate").permitAll()
            .and().formLogin()
            .loginPage("/login").loginProcessingUrl("/validate")
            .and()
            .logout().and().httpBasic().and().authorizeRequests().anyRequest().authenticated();
    }
}

I need to figure out how to not lose the redirect information. I can provide any additional information needed. I am wasting tons of time trying to figure this out. I would appreciate any input. Thanks.


Get this bounty!!!

#StackBounty: #hibernate #spring-boot #jpa #kotlin #jpql JPQL and list of tuples as parameter for SELECT IN statements

Bounty: 50

Given the following table layout:

CREATE TABLE things (
    id      BIGINT PRIMARY KEY NOT NULL,
    foo     BIGINT NOT NULL,
    bar     BIGINT NOT NULL
);

An entity class (Kotlin):

@Entity
@Table(name = "things")
class Thing(
        val foo: Long,
        val bar: Long
) : AbstractPersistable<Long>()

And a repository:

interface ThingRepository : JpaRepository<Thing, Long> {
@Query("SELECT t FROM Thing t WHERE t.foo IN ?1")
fun selectByFoos(foos: Iterable<Long>): Iterable<Thing>

@Query("SELECT t FROM Thing t WHERE (t.foo, t.bar) IN ((1, 2), (3, 4))")
fun selectByFoosAndBarsFixed(): Iterable<Thing>

@Query("SELECT t FROM Thing t WHERE (t.foo, t.bar) IN ?1")
fun selectByFoosAndBars(foosAndBars: Iterable<Pair<Long, Long>>): Iterable<Thing>

The following two calls work fine:

repo.selectByFoos(listOf(1L, 3L))
repo.selectByFoosAndBarsFixed()

However the this one does not:

repo.selectByFoosAndBars(listOf(Pair(1L, 2L), Pair(3L, 4L)))

It throws:

org.springframework.dao.DataIntegrityViolationException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.DataException: could not extract ResultSet

Caused by: org.h2.jdbc.JdbcSQLException: Data conversion error converting "aced00057372000b6b6f746c696e2e50616972fa1b06813de78f780200024c000566697273747400124c6a6176612f6c616e672f4f626a6563743b4c00067365636f6e6471007e000178707372000e6a6176612e6c616e672e4c6f6e673b8be490cc8f23df0200014a000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000000000000017371007e00030000000000000002"; SQL statement:
/* SELECT t FROM Thing t WHERE (t.foo, t.bar) IN ?1 */ select thing0_.id as id1_0_, thing0_.bar as bar2_0_, thing0_.foo as foo3_0_ from things thing0_ where (thing0_.foo , thing0_.bar) in (? , ?) [22018-197]

Caused by: java.lang.NumberFormatException: For input string: "aced00057372000b6b6f746c696e2e50616972fa1b06813de78f780200024c000566697273747400124c6a6176612f6c616e672f4f626a6563743b4c00067365636f6e6471007e000178707372000e6a6176612e6c616e672e4c6f6e673b8be490cc8f23df0200014a000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000000000000017371007e00030000000000000002"

I guess the elements of the list passed as parameter are not inserted correctly into the query. How can I correct this?

Sure, I could manually build the query, like so:

@Repository
class SecondThingRepository(private val entityManager: EntityManager) {
    fun selectByFoosAndBars(foosAndBars: Iterable<Pair<Long, Long>>): Iterable<Thing> {
        val pairsRepr = foosAndBars.joinToString(prefix = "(", postfix = ")") { "(${it.first}, '${it.second}')" }
        val query: TypedQuery<Thing> = entityManager.createQuery("SELECT t FROM Thing t WHERE (t.foo, t.bar) IN $pairsRepr", Thing::class.java)
        return query.resultList
    }
}

But this seems note very good.


Get this bounty!!!

#StackBounty: #java #spring #spring-boot #svg #batik Unable to make sense of URL for connection reading a svg file

Bounty: 50

I have a Spring Boot v2.1.2.RELEASE application.
I have a file in ../src/main/resources/icons/128/black/ae.png

which I want to read, But I got an error: Unable to make sense of URL for connection

@SpringBootApplication
public class SvgManagerApplication implements CommandLineRunner {

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


    @Override
    public void run(String... args) throws Exception {      

        try {

            String parser = XMLResourceDescriptor.getXMLParserClassName();
            SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
            Document doc = f.createDocument("classpath:icons/128/black/ae.svg");

            System.out.println(doc);

        } catch (IOException ex) {

            System.out.println(ex.getMessage());

        }
    }
}


Get this bounty!!!

#StackBounty: #java #mysql #spring-boot #jpa Spring JPA OneToOne FK as PK Cascade.Remove

Bounty: 50

I’ve got two tables, b and a:

  • they have a one-to-one bidirectional relationship
  • a has a foreign key to b that defines this relationship
  • this foreign key is also considered as a primary key for a, and a JPA @ID
  • I want a cascade removal that deletes the related b when a is deleted
  • in MySQL, a‘s b_id is NOT NULL

The problem is that when I delete my A object with JPA repository, I get a ConstraintViolationException on its foreign key.
I would expect that both a and b rows are deleted (cleverly starting with a‘s one).

How could I work around this knowing that I want to keep:

  • my DB schema the same
  • the cascade removal from a to b
  • the b id being the JPA @Id for a
CREATE TABLE `b` (
  `dbid` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`dbid`),
);

CREATE TABLE `a` (
  `b_id` int(11) NOT NULL,
  KEY `b_fk` (`b_id`),
  CONSTRAINT `b_fk` FOREIGN KEY (`b_id`) REFERENCES `b` (`dbid`),
);

@Entity
@Table(name = "a")
public class A {

    @Id
    @Column(name = "b_id")
    @GeneratedValue(generator = "gen")
    @GenericGenerator(name = "gen", strategy = "foreign", parameters = @Parameter(name="property", value="b"))
    private Integer bId;

    @OneToOne(cascade = CascadeType.REMOVE)
    @PrimaryKeyJoinColumn
    private B b;
}
@Entity
@Table(name = "b")
public class B {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name = "dbid")
    private Integer id;

    @OneToOne(mappedBy = "b")
    private A a;
}


Get this bounty!!!

#StackBounty: #java #hibernate #spring-boot #multi-tenant Springboot Multi-tenant with MultiTenantConnectionProvider always throw org.a…

Bounty: 50

I have started converted my exiting Spring Boot(1.5.4.RELEASE) application to work with multi-tenant features.it is a schema based multi-tenant solution and based on mysql.
As hibernate document suggested below

https://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch16.html

i have implemented both MultiTenantConnectionProvider and CurrentTenantIdentifierResolver interfaces and it works fine.

package com.ifi.aws.tenant.config.hibernate;

import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ifi.aws.tenant.entity.TenantContext;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

@Component
public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {

  private static final long serialVersionUID = 6246085840652870138L;

  @Autowired
  private DataSource dataSource;

@Override
public Connection getAnyConnection() throws SQLException {
  return dataSource.getConnection();
}

@Override
public void releaseAnyConnection(Connection connection) throws SQLException {
  connection.close();
}

@Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
  final Connection connection = getAnyConnection();
  try {
    connection.createStatement().execute( "USE " + tenantIdentifier );
  }
  catch ( SQLException e ) {
    throw new HibernateException(
        "Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]",
      e
      );
  }
  return connection;
}

@Override
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
  try {
    connection.createStatement().execute( "USE " + TenantContext.DEFAULT_TENANT );
  }
  catch ( SQLException e ) {
    throw new HibernateException(
        "Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]",
      e
      );
  }
  connection.close();
}

@SuppressWarnings("rawtypes")
@Override
public boolean isUnwrappableAs(Class unwrapType) {
  return false;
}

@Override
public <T> T unwrap(Class<T> unwrapType) {
  return null;
}

@Override
public boolean supportsAggressiveRelease() {
  return true;
}

}

package com.ifi.aws.tenant.config.hibernate;

import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.springframework.context.annotation.Configuration;

import com.ifi.aws.tenant.entity.TenantContext;

@Configuration
public class TenantIdentifierResolver implements CurrentTenantIdentifierResolver {

  @Override
  public String resolveCurrentTenantIdentifier() {


     String tenantId = TenantContext.getTenantSchema();

    //System.out.println("------------------ resolveCurrentTenantIdentifier = " + tenantId);
    if (tenantId != null) {
        return tenantId;
    }
    return TenantContext.DEFAULT_TENANT;
}
@Override
public boolean validateExistingCurrentSessions() {
    return true;
}
}

and then below is my hibernate configuration

package com.ifi.aws.tenant.config.hibernate;

import org.hibernate.MultiTenancyStrategy;
import org.hibernate.cfg.Environment;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import 
org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

@Configuration
public class HibernateConfig {

  @Autowired
  private JpaProperties jpaProperties;

  @Bean
  public JpaVendorAdapter jpaVendorAdapter() {
    return new HibernateJpaVendorAdapter();
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource,
  MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
  CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl) {
    Map<String, Object> properties = new HashMap<>();
    properties.putAll(jpaProperties.getHibernateProperties(dataSource));
    properties.put(Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA);
    properties.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProviderImpl);
    properties.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolverImpl);

    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource);
    em.setPackagesToScan("com.ifi.aws");
    em.setJpaVendorAdapter(jpaVendorAdapter());
    em.setJpaPropertyMap(properties);
   return em;
  }
}

however time to time system crashes with below error

Springboot Multi-tenant with MultiTenantConnectionProvider always throw org.apache.tomcat.jdbc.pool.PoolExhaustedException: [http-nio-8086-exec-2] Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[size:100; busy:100; idle:0; lastwait:30000].

i Did some reading on this site and found exact same issue in below questions.

Spring Boot: Apache derby pool empty. Unable to fetch a connection in 30 seconds
Tomcat Connection Pool Exhasuted

One of the fixes they suggested was to to add below configurations

spring.datasource.tomcat.max-active=100
spring.datasource.tomcat.max-idle=8
spring.datasource.tomcat.min-idle=8

But still i am getting the same error and i debug the code and found that it closes the connection after each execution of the database call. Do you guys have any idea?

Thanks,
Kelum


Get this bounty!!!