Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirecting user to oauth2 authorization server to get token Spring Boot

I have 2 apps running, one is resource server where I have the info that needs authentication to view the text. Then I have authorization server that gives tokens. Right now I can use postman or Insomnia, add the auth_url, token_url, client_id, client_secret and I get the token. I add the token to header and i get do a get request to my resource server using header, and it works just fine.

Now i have no idea how to implement redirection from my resource server directly. Like when I go to

localhost:9000/home

I'd like to get redirected to:

localhost:9001/login

where I login with my inmemory user then it redirects me back to localhost:9000/home and I see the message.

What would be the best way to implement a way for user to access information on localhost:9000/home. You go to localhost:9000/home, it goes to authorization server on localhost:9001, you log in with username and password. Approve the grant, and it puts you back to localhost:9000/home and then you can see the text, what was previously protected, because you didn't have token to access it.

ResourceServer.java

@SpringBootApplication
@RestController
@EnableResourceServer
@EnableOAuth2Client
public class SampleResourceApplication extends ResourceServerConfigurerAdapter {
        @Override
    public void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/", "/login**").hasRole("user")
                .anyRequest().authenticated();
    }

    @Bean
    public RequestContextListener requestContextListener() {
        return new RequestContextListener();
    }

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

    @RequestMapping("/home")
    public String home() {
        return "this is home";
    }

}

and my properties looks like:

server:
  port: 900
security:
  oauth2:
    client:
      client-id: foo
      client-secret: foosecret
      access-token-uri: http://localhost:9001/auth/oauth/token
      user-authorization-uri: http://localhost:9001/auth/oauth/authorize
      grant-type: USER
      auto-approve-scopes: true
    resource:
      user-info-uri: http://localhost:9001/auth/user
like image 428
Jan Avatar asked Jul 21 '17 07:07

Jan


2 Answers

Let's separate the agents: You have the user (i.e. you, also know as the resource owner), the authorization server, the resource server and the client (the application that access your urls, i.e. your browser).

Normally, this happens in your situation:

  1. When your client access the resource server, it receives a 401. Depending of your implementation, you could also directly redirect the client to your AS (using a simple redirect response).
  2. Your AS prompts you for credentials. After validating them, it issues a token for you. You can then use this token to access the RS.

What you're trying to get (if I understand correctly) is to redirect with the token automatically. To achieve this, you can simply pass the url you tried to reach (i.e. localhost:9000/home) when you redirect to your AS at the end of step 1. Your AS hten prompts the user for credentials, generate the token, stores it as a cookie (in the case of a browser), and redirects you to the url he received (localhost:9000/home).

EDIT: what's the resulting code for the redirection.

When you get to the configure, you first check if the user is authenticated. If he is, then all's fine, but if he isn't, you must catch this event and start your redirection. This can be done using the exceptionHandling method of the chaining http:

public void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/**")
            .authorizeRequests()
            .antMatchers("/", "/login**").hasRole("user")
            .anyRequest().authenticated()
    .and()
            .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint());
}

private AuthenticationEntryPoint authenticationEntryPoint() {
    return new AuthenticationEntryPoint() {
        // You can use a lambda here
        @Override
        public void commence(HttpServletRequest aRequest, HttpServletResponse aResponse,
               AuthenticationException aAuthException) throws IOException, ServletException {
            aResponse.sendRedirect(MY_AS_URL + "?redirect_uri=localhost:9001/home");
        }
    };
}
like image 112
Turtle Avatar answered Sep 28 '22 07:09

Turtle


Unfortunately, I am not familiar with the Spring framework, but hopefully this helps anyways:

OAuth is an authorization protocol. It does not handle authentication (see also: "What is the difference between authentication and authorization?" on ServerFault).

If I understand you correctly, you want users to be redirected to /login when they go to /home and aren't already logged-in. This step has nothing to do with OAuth, it must be part of your application's security / firewall setup.

Please also note that there is a difference between logging in (authenticating) on the authorization server and actually granting the application the right to access your resources (authorization). First you have to prove who you are and only then can you give access to your stuff. These are two separate steps.

like image 21
paolo Avatar answered Sep 28 '22 06:09

paolo