All Products
Search
Document Center

Resource Access Management:Configurations for OAuth SDKs

Last Updated:Oct 14, 2024

This topic describes the related configurations of some commonly used SDKs of Open Authorization (OAuth). In this topic, configurations by using Spring Boot and OAuth 2.0 are provided.

Prerequisites

Modify configuration files

Modify the following configuration files. For more information, see Spring Boot and OAuth2.

  • Create the core configuration file application.yml or application.yaml in the src/main/resources directory of a Spring Boot project. The following sample code provides a configuration example:

    spring:
      security:
        oauth2:
          client:
            registration:
              alibabacloud:
                client-id: 415195082384692****
                client-secret: 6EwN4qutnZuchG6n677Ie33SsjAhwyTpcOMSoIo6v0gqJtw4QcHhERVXfqzc****
                client-authentication-method: client_secret_basic
                authorization-grant-type: authorization_code
                redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
                client-name: alibabacloud
            provider:
                alibabacloud:
                  authorization-uri: https://signin.alibabacloud.com/oauth2/v1/auth
                  token-uri: https://oauth.alibabacloud.com/v1/token
                  user-info-uri: https://oauth.alibabacloud.com/v1/userinfo
                  user-name-attribute: sub
                  jwk-set-uri: https://oauth.alibabacloud.com/v1/keys
  • Add the following dependencies to the pom.xml file:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
        <relativePath /> 
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
            </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>js-cookie</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
    </dependencies>

Complete sample code

Backend code

Deploy a secure Web application based on the Spring Security backend framework that incorporates authentication, authorization, error handling, and cross-site request forgery (CSRF) protection. In the following example, the RESTful API controller WebApplication is defined. The controller processes HTTP requests and is integrated with the OAuth 2.0 authentication system.

  • The private variable handler is defined as an AuthenticationEntryPointFailureHandler instance and is used to handle failures at the authentication entry point. When a user attempts to access a page that requires authentication but authentication fails, the handler sets the HTTP status code to 401 and returns the "Unauthorized" error message.

  • The WebApplication class provides a GET mapping to the /user path. If a GET request is sent to the /user path, the method specified in the GET mapping is called. The method receives an OAuth2User object as a parameter. The OAuth2User object represents the OAuth2 information of the authenticated user. Then, the method returns a Map object that contains the username. The username is obtained from the attributes of the OAuth2User object.

  • In the configure method of the WebApplication class, the HttpSecurity object is configured to implement the security policy for the web application. In the HttpSecurity object, paths that allow anonymous access are configured, including /, /error, and webjars. In the HttpSecurity object, identity authentication for requests to access the other paths is also configured. Thus, only authenticated users can access the paths.

  • In the configure method, error handling is configured. If an error occurs because a user is unauthorized, the 401 status code is returned, and the defined variable handler is used to handle the authentication failure. In the configure method, the OAuth2 logon feature is configured to handle logon failures. If logon fails, an error message is configured in the user session, and the handler is called to handle the failure.

  • In the configure method, the logout feature is configured. If a user logs out, the user is redirected to /. All users can log out.

  • In the configure method, CSRF protection is configured. CookieCsrfTokenRepository is used to store CSRF tokens, and the HttpOnly attribute is disabled to improve security. An additional GET mapping to the error method is configured to handle error requests. The error method obtains error messages from the user session and removes the error messages before the error messages are returned. This way, the error messages are not repeatedly displayed to users.

    import org.springframework.boot.SpringApplication;
    import org.springframework.http.HttpStatus;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.core.annotation.AuthenticationPrincipal;
    import org.springframework.security.oauth2.core.user.OAuth2User;
    import org.springframework.security.web.authentication.AuthenticationEntryPointFailureHandler;
    import org.springframework.security.web.authentication.HttpStatusEntryPoint;
    import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
    import org.springframework.web.bind.annotation.GetMapping;
    import javax.servlet.http.HttpServletRequest;
    import java.util.Collections;
    import java.util.Map;
    
    public class WebApplication extends WebSecurityConfigurerAdapter {
    
        private AuthenticationEntryPointFailureHandler handler = new AuthenticationEntryPointFailureHandler((request, response, authException) -> response.sendError(401, "Unauthorized"));
    
        @GetMapping("/user")
        public Map<String, Object> user(@AuthenticationPrincipal OAuth2User principal) {
            return Collections.singletonMap("name", principal.getAttribute("name"));
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests(a -> a
                            .antMatchers("/", "/error", "/webjars/**").permitAll()
                            .anyRequest().authenticated()
                    )
                    .exceptionHandling(e -> e
                            .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
                    )
                    .oauth2Login(o -> o
                            .failureHandler((request, response, exception) -> {
                                request.getSession().setAttribute("error.message", exception.getMessage());
                                handler.onAuthenticationFailure(request, response, exception);
                            })
                    )
                    .logout(l -> l
                            .logoutSuccessUrl("/").permitAll()
                    )
                    .csrf(c -> c
                            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                    );
        }
    
        @GetMapping("/error")
        public String error(HttpServletRequest request) {
            String message = (String) request.getSession().getAttribute("error.message");
            if (message != null) {
                request.getSession().removeAttribute("error.message");
            }
            return message;
        }
    }

Frontend code

Create the index.html file in the src/main/resources/static directory of the project for verification. The following sample code provides a configuration example:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <title>Demo</title>
    <meta name="description" content=""/>
    <meta name="viewport" content="width=device-width"/>
    <base href="/"/>
    <link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css"/>
    <script src="/webjars/jquery/jquery.min.js"></script>
    <script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
    <script src="/webjars/js-cookie/js.cookie.js">
        $.ajaxSetup({
            beforeSend: function (xhr, settings) {
                if (settings.type === 'POST' || settings.type === 'PUT' || settings.type === 'DELETE') {
                    if (!(/^(http:\/\/|https:\/\/)/.test(settings.url))) {
                    xhr.setRequestHeader("X-XSRF-TOKEN", Cookies.get('XSRF-TOKEN'));
                }
            }
        }
    });
    </script>
</head>

<body>
<h1>Demo</h1>
<div class="container text-danger error"></div>
<script>
    $.get("/error", function (data) {
        if (data) {
            $(".error").html(data);
        } else {
            $(".error").html('');
        }
    });
</script>
<div class="container unauthenticated">
    With Aliyun: <a href="/oauth2/authorization/aliyun">click here</a>
</div>
<div class="container authenticated">
    With Google: <a href="/oauth2/authorization/google">click here</a>
</div>
<script type="text/javascript">
    $.get("/user", function(data) {
        $("#user").html(data.name);
        $(".unauthenticated").hide()
        $(".authenticated").show()
    });
</script>
<div class="container authenticated">
    Logged in as: <span id="user"></span>
    <div>
        <button onClick="logout()" class="btn btn-primary">Logout</button>
    </div>
</div>

<script type="text/javascript">
    var logout = function() {
        $.post("/logout", function() {
            $("#user").html('');
            $(".unauthenticated").show();
            $(".authenticated").hide();
        })
        return true;
   }
</script>
</body>
</html>

Verification

Run the sample codes and access http://localhost:8080 in a browser after the project starts.

References

Manage permissions of a third-party application