Okta SSO w/ react and spring boot

Has anyone successfully set this up, I’ve been through just about all the tutorials I can find and to no avail i’m still running into the following error

org.springframework.security.oauth2.client.resource.UserRedirectRequiredException: A redirect is required to get the users approval

I have a SPA in Okta and I’m using Implicit grant type.

I haven’t seen this exception before. Is this happening when the user is being redirected back to your application after login?

Yes, sign in works fine. But upon redirecting to the app or any of the routes I get the above mentioned error.

I think I’m going to wait for my java experts to come online (it is still early on the west coast). @mraible any thoughts here?

I did run through this tutorial to UAT it a few weeks ago, and can guarantee it is working:
https://developer.okta.com/quickstart/#/react/java/spring

Agreed, I ran through the same tutorial and it did work, but when I apply it to my existing project I get that error. Thanks a bunch for your help so far, I’ll keep an eye one the thread throughout the day.

I think first thing Raible is going to want is to see some configuration or code or something, is there anything you can share?

Oh sure, for signin I followed this tutorial OktaSignWidget react

My spring boot sever application.properties has the following properties
okta.oauth2.issuer=https://dev-{url}.oktapreview.com/oauth2/default
okta.oauth2.client-id={companyClientId}

And the reset is exactly as shown in the tutorial you posed above.

Do you have @EnableResourceServer configured in your Spring Boot app?

I do not, might you have a link on how to set up @EnableResourceServer? I’ve found something on the spring website but it’s not really clear. Thanks again!

The Okta Spring Boot Starter has a code sample:

@EnableResourceServer
@SpringBootApplication
@RestController
public class ExampleApplication {

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

    @GetMapping("/hello-oauth")
    public String sayHello(Principal principal) {
        return "Hello, " + principal.getName();
    }
}

Make sure to mark the application with Spring Security’s @EnableResourceServer annotation, to enable handing of access tokens.

My requests seem to be coming through to the sever but then they throw 500s.

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.lang.IllegalArgumentException: URI must not be null path:/my/uri

Do you have @RestController on your controller and a @GetMapping? If so, you should see a result in your browser. If not, this basic tutorial might help: https://developer.okta.com/blog/2017/03/21/spring-boot-oauth.

Yes I have both, and neither my @GetMapping nor my @PostMapping’s are working, all throw the above mentioned error. I ran through the basic tutorial and I was able to get that working.

Is it possible for you to post your project to GitHub or somewhere similar so I can take a look?

Sadly I can not, as it’s not open source. I’m going to try starting from scratch again and hope that does it.

On a side note, would it make more sense to try and use a Web Application Type with an Authorization Code in Okta? We have several of those that are working, I just didn’t see anything on your site to get a React app working with the Web Application Type.

You could do this, and leverage cookies to talk to your Spring Boot application. We do this in JHipster. After you configured SSO on the Spring Boot side, you’d just need to hit http://localhost:8080/login from your React app to log in.

I figured it out, I needed a WebSecurityConfigurerAdapter for my routes/REST calls. Once that was configured, I was able to get a response from both POST and GET api calls.

Thanks so much for your help.

1 Like

I’m running my spring boot application in tomcat. Everything works locally running the client from localhost:3000 to my tomcat server localhost:8080.

When I try to log into the app using the client from the deployed war I get the a 404 from the /implicit/callback#id_token

The 404 description is
The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

I have a feeling it’s trying to go to the route /implicit/callback and something isn’t redirecting correctly.
React OktaSigninWidget

describes /implicit/callback as A route to parse tokens after a redirect. does this work the same if redirecting within a container?

below is my code:

Spring Stuff

@EnableResourceServer
@SpringBootApplication
@RestController
public class MyersSixModule extends SpringBootServletInitializer {

public static void main(String[] args) {
	SpringApplication app = new SpringApplication(MyersSixModule.class);
	Properties properties = new Properties();

	// Add root to static locations so HTML files can be read
	properties.setProperty("spring.resources.staticLocations", "classpath:/");
	app.setDefaultProperties(properties);
	app.run(args);
}

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

@GetMapping("/hello-oauth")
public String sayHello(Principal principal) {
	return "Hello, " + principal.getName();
}
}


@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
	.cors().disable().csrf().disable()
    .authorizeRequests()
      .antMatchers("/**",
	          "/static/**",
	          "/images/**",
	          "/logout**",
	          "/loggedOut**",
	          "/data**",
	          "/sixmodule/**",
	          "/login**",
	          "/implicit/**",
	          "/**/callback**").permitAll()
      .anyRequest().authenticated();
    // Allow pages from same site to be put in iframe
	http.headers().frameOptions().disable();
}

}

figured I’d put what my solution was just incase anyone goes looking for it. It’s from the Spring website and is an angular example but the Spring Boot part stays the same.

Using Natural Routes

Cheers!
Thanks a bunch for your help

2 Likes

Thanks for replying with the solution! Hope you have a nice weekend. :slight_smile: