11

I've been thrashing around with the Spring Boot Oauth2 tutorial and I can't seem to get a pretty key element working:

https://spring.io/guides/tutorials/spring-boot-oauth2/

I want to run as an authorization server. I've followed the instructions as closely as I can fathom, but when I go to the /oauth/authorize endpoint, all I ever get is a 403 Forbidden response. This actually makes sense to me given the HttpSecurity configuration that the tutorial sets up:

protected void configure(HttpSecurity http) throws Exception {
    http
      .antMatcher("/**")
      .authorizeRequests()
        .antMatchers("/", "/login**", "/webjars/**")
        .permitAll()
      .anyRequest()
        .authenticated()
        .and().logout().logoutSuccessUrl("/").permitAll()
        .and().csrf().csrfTokenRepository(csrfTokenRepository())
        .and().addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
        .addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
}

The login page for this tutorial is actually the main index and I definitely don't see anything in the tutorial that would instruct the Oauth system to redirect the login flow there.

I can get it kind of working by adding this:

        .and().formLogin().loginPage("/")

...but before moving forward I really wanted to understand if this is a problem with the tutorial or my implementation of it or something else. What is the mechanism by which the Oauth security system decides what a "login" page is?

Ryan
  • 545
  • 1
  • 5
  • 16
  • Hi @Ryan, did you already solve this? – Ralph Rimorin Mar 20 '16 at 15:41
  • I came up with a solution, but it doesn't explain how the sample was supposed to work. So I'm still not sure what would have caused the security system to redirect to "/" for authentication in this example. I'll post my solution below for what it's worth. – Ryan Mar 21 '16 at 16:24
  • Can you post it? Let me try to explain if I could dig something. – Ralph Rimorin Mar 22 '16 at 18:02

3 Answers3

10

The solution was to add the following to the SecurityConfig.configure call:

@Override
protected void configure(HttpSecurity http) throws Exception {
    AuthenticationEntryPoint aep = new AuthenticationEntryPoint() {

        @Override
        public void commence(HttpServletRequest request,
                HttpServletResponse response,
                AuthenticationException authException) throws IOException,
                ServletException {
            response.sendRedirect("/login");
        }
    };

    http.exceptionHandling()
            .authenticationEntryPoint(aep)

Which redirects the authentication flow to a specific URL (in this case I am sending it to "/login", but it also worked with "/" or anything else I chose). I have no idea how the tutorial is supposed to do the redirect without explicitly adding this line.

Ryan
  • 545
  • 1
  • 5
  • 16
3

Please follow this answer. 1. You have to setup the headers on your Apache proxy:

<VirtualHost *:443>
    ServerName www.myapp.org
    ProxyPass / http://127.0.0.1:8080/
    RequestHeader set X-Forwarded-Proto https
    RequestHeader set X-Forwarded-Port 443
    ProxyPreserveHost On
    ... (SSL directives omitted for readability)
</VirtualHost>

2. You have to tell your Spring Boot app to use these headers. So put the following line in your application.properties (or any other place where Spring Boots understands properties):

server.use-forward-headers=true
Community
  • 1
  • 1
Kushal
  • 103
  • 1
  • 11
-1

You don't need to go to the /oauth/authorize endpoint directly. That is used behind the scenes and the index.html page is the one that the tutorial is demonstrating.

Kim
  • 150
  • 7
  • Later in the tutorial we set up a second service that uses the first as an authorization server. It sets up oauth/authorize as the user authorization endpoint. The authorization server should redirect to a login page. This works with form authentication, but not as constructed with the external social logins: "To test the new features you can just run both apps and visit 127.0.0.1:9999 in your browser. The client app will redirect to the local Authorization Server, which then gives the user the usual choice of authentication with Facebook or Github." – Ryan Mar 14 '16 at 05:04
  • Ok, your original question made it sound like you were going to /oauth/authorize and not to your client app. – Kim Mar 16 '16 at 15:41
  • I've set up this tutorial before and have not gotten the 403 error when in this part of the tutorial, but your code you've pasted (minus the loginPage() section) looks correct. So, the failure to redirect to / must be coming from a different section of code. The app should be going to / by default. so calling the formLogin() command shouldn't be necessary unless you are putting the login page somewhere other than / . In another app, I have it set to /login, so I use that command. There should be anything wrong with using the formLogin() command if you need to. – Kim Mar 16 '16 at 15:46
  • The client app wasn't working, so I went to oauth/authorize directly to see what the problem was. This should redirect to the login page, but I don't see how that redirect gets set up. I would really like to understand how the underlying framework is handling this case--let's say I wanted my login to be at some other path--how would I set this up? – Ryan Mar 17 '16 at 16:14
  • You'd set this up exactly like you did - .and().formLogin().loginPage("/mycustomloginpage") – Kim Mar 18 '16 at 14:10