title: Spring-Boot OAuth2 Strange Behavior When Authenticating with Twitch
body: <p>I have been trying to set up OAuth2 with Twitch through Spring for a few days now. I have resolved quite a few problems in that process but this one has stumped me. When I attempt to access one of the endpoints that I am trying to require users to be authenticated with Twitch for I am getting redirected to localhost:8080/login and being shown a page that simply reads &quot;Login with OAuth 2.0&quot; and has nothing else on it. My expectation was that Spring would automatically redirect me to Twitch's authentication portal and then Twitch would send me back to the Spring application after going through the OAuth process. Instead I am simply being shown that page and nothing is happening.</p>
  <p>As far as what has been done so far to remedy this problem... pretty much nothing. I have not been able to find anyone else running into this problem so I am thinking that there are a few possible issues... Based on this tutorial <a href="https://spring.io/guides/tutorials/spring-boot-oauth2/" rel="nofollow noreferrer">https://spring.io/guides/tutorials/spring-boot-oauth2/</a> it seems like Spring has out of the box functionality for a lot of different OAuth providers. I am guessing that Twitch is not one of them. That makes me concerned that something on Twitch's backend might be causing this problem for Spring (if that is the case then I will need to make a custom authenticator). The other possibility I have thought of is that Spring might need to be told where to redirect users to for them to get authenticated. If that is the case then I would appreciate some help with that as I have not been able to find any indication that that is something that needs to be done online (and I have no idea how to do it).</p>
  <p>Some important files from my project:</p>
  <p>pom.xml:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  &lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
           xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
      &lt;parent&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
          &lt;version&gt;2.5.7&lt;/version&gt;
          &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;
      &lt;/parent&gt;
      &lt;groupId&gt;com.redacted&lt;/groupId&gt;
      &lt;artifactId&gt;redacted&lt;/artifactId&gt;
      &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
      &lt;name&gt;redacted&lt;/name&gt;
      &lt;description&gt;redacted&lt;/description&gt;
      &lt;properties&gt;
          &lt;java.version&gt;17&lt;/java.version&gt;
      &lt;/properties&gt;
      &lt;dependencies&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
              &lt;artifactId&gt;lombok&lt;/artifactId&gt;
              &lt;optional&gt;true&lt;/optional&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.apache.tomcat.embed&lt;/groupId&gt;
              &lt;artifactId&gt;tomcat-embed-jasper&lt;/artifactId&gt;
              &lt;version&gt;9.0.44&lt;/version&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
              &lt;version&gt;2.4.4&lt;/version&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-oauth2-client&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
              &lt;artifactId&gt;jstl&lt;/artifactId&gt;
              &lt;version&gt;1.2&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.security&lt;/groupId&gt;
              &lt;artifactId&gt;spring-security-test&lt;/artifactId&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-rest&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;com.h2database&lt;/groupId&gt;
              &lt;artifactId&gt;h2&lt;/artifactId&gt;
          &lt;/dependency&gt;
      &lt;/dependencies&gt;
  
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                  &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
                  &lt;configuration&gt;
                      &lt;excludes&gt;
                          &lt;exclude&gt;
                              &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
                              &lt;artifactId&gt;lombok&lt;/artifactId&gt;
                          &lt;/exclude&gt;
                      &lt;/excludes&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;
  
  &lt;/project&gt;
  </code></pre>
  <p>application.properties:</p>
  <pre><code>spring.mvc.view.prefix=/WEB-INF/jsp/
  spring.mvc.view.suffix=.jsp
  
  spring.security.oauth2.client.registration.twitch.client-id=redacted
  spring.security.oauth2.client.registration.twitch.client-secret=redacted
  spring.security.oauth2.client.registration.twitch.client-authentication-method=post
  spring.security.oauth2.client.registration.twitch.redirect-uri=http://localhost:8080/login/oauth2/code/twitch
  spring.security.oauth2.client.registration.twitch.provider=twitch
  spring.security.oauth2.client.registration.twitch.scope=user:read:email
  spring.security.oauth2.client.registration.twitch.authorization-grant-type=AUTHORIZATION_CODE
  
  spring.security.oauth2.client.provider.twitch.authorization-uri=https://id.twitch.tv/oauth2/authorize
  spring.security.oauth2.client.provider.twitch.token-uri=https://id.twitch.tv/oauth2/token
  spring.security.oauth2.client.provider.twitch.user-info-uri=https://id.twitch.tv/oauth2/userinfo
  spring.security.oauth2.client.provider.twitch.user-name-attribute=redacted
  
  </code></pre>
  <p>and also my SpringSecurityConfiguration file in the event it matters:</p>
  <pre><code>package com.redacted;
  
  import org.springframework.context.annotation.Configuration;
  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;
  
  @Configuration
  @EnableWebSecurity
  public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {
  
      @Override
      public void configure(HttpSecurity httpSecurity) throws Exception {
          //This allows users to access the &quot;/&quot; and &quot;/Info&quot; endpoints without authenticating with Twitch. To go anywhere else they will have to authenticate.
          httpSecurity.antMatcher(&quot;/**&quot;).authorizeRequests().antMatchers(&quot;/&quot;, &quot;/Info&quot;).permitAll().anyRequest().authenticated().and().oauth2Login();
      }
  }
  </code></pre>
  <p>My project structure:</p>
  <p><a href="https://i.stack.imgur.com/QjglS.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QjglS.png" alt="A picture of my project structure" /></a></p>
  <p>Thank you for your time and consideration, I appreciate the help.</p>
  <p>-Epoch</p>
  <p>Edit:</p>
  <p>Something I have recently found that I thought might be prudent to add to this discussion - when I am attempting to access a secured page in my current setup I see this screen: <a href="https://i.stack.imgur.com/MuSDd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/MuSDd.png" alt="enter image description here" /></a></p>
  <p>It looks as if the intended way Spring normally displays this screen is like this: <a href="https://i.stack.imgur.com/97t5w.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/97t5w.png" alt="enter image description here" /></a></p>
  <p>It's almost as if Spring simply is not seeing my Oauth provider. Not sure if this information is helpful but I thought I would include it. Springs intended behavior for Oauth is that when there is only one provider configured the /login page is skipped altogether. I would actually prefer this behavior to be exhibited (but given it sees no providers I presume it shows the page).</p>