Example Main Content

  • 1. Multi-authentication mode (password mode, client mode)
  • 2. Save token to Redis support
  • 3. Resource protection
  • 4. Save the password mode user and permission to the database
  • 5. Instructions

Example code – Github

introduce

Oauth2 Client Credentials Client mode Process for obtaining access_token

The Client Credentials Grant allows clients to authenticate to the service provider in their own name, not the user’s. Strictly speaking, the client-side pattern is not the problem that the OAuth framework addresses. In this model, users register directly with the client, and the client requests services from the “service provider” in its own name, with no authorization issues.

  • (A) The client authenticates to the authentication server and asks for an access token. HTTP requests sent by clients contain the following parameters: grantType: indicates the authorization type. The value is always clientcredentials. Scope: indicates the permission scope. This option is optional.

  • (B) After the authentication server confirms that it is correct, it provides the client with access token.

Oauth2 password Password mode Process for obtaining an Access_token

In the Resource Owner Password Credentials Grant mode, users provide their user names and passwords to clients. The client uses this information to request authorization from the “service provider.” In this mode, the user must give his password to the client, but the client cannot store the password. This is usually used when the user has a high degree of trust in the client, such as when the client is part of the operating system or is produced by a well-known company. Authentication servers can only consider using this mode if other authorization modes cannot be implemented.

  • (A) The user provides the user name and password to the client.

  • (B) The client sends the user name and password to the authentication server and requests the token from the authentication server. The HTTP request sent by the client contains the following parameters: grant_type: specifies the authorization type. The value is “password” (mandatory). Username: indicates the username. This parameter is mandatory. Password: indicates the user password. This parameter is mandatory. Scope: indicates the permission scope. This option is optional.

  • (C) After the authentication server confirms that it is correct, it provides the client with access token.

Default endpoints provided by Oauth2 (EndPoints)

  • /oauth/authorize: Authorize endpoints
  • /oauth/token: token endpoint
  • /oauth/confirm_access: User confirms authorization submission endpoint
  • /oauth/error: authorization service error message endpoint
  • /oauth/check_token: token resolution endpoint for resource service access
  • /oauth/token_key: Provides the endpoint of the public key, if the JWT token is used

Example Usage

1. Obtain the access_token in terminal mode

http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=123456

Returns the result

{
    "access_token": "67a2c8f6-bd08-4409-a0d6-6ba61a4be950"."token_type": "bearer"."expires_in": 41203."scope": "select"
}
Copy the code

2. Obtain the access_token in password mode

http://localhost:8080/oauth/token?username=user&password=123456&grant_type=password&scope=select&client_id=client_2&clie nt_secret=123456

Returns the result

{
    "access_token": "b3d2c131-1225-45b4-9ff5-51ec17511cee"."token_type": "bearer"."refresh_token": "8495d597-0560-4598-95ef-143c0855363c"."expires_in": 42417."scope": "select"
}
Copy the code

3. Refresh access_token

http://localhost:8080/oauth/token?grant_type=refresh_token&refresh_token=8495d597-0560-4598-95ef-143c0855363c&client_id= client_2&client_secret=123456

Returns the result

{
    "access_token": "63de6c71-672f-418c-80eb-0c9abc95b67c"."token_type": "bearer"."refresh_token": "8495d597-0560-4598-95ef-143c0855363c"."expires_in": 43199."scope": "select"
}
Copy the code

4. Access protected resources

http://localhost:8080/order/1?access_token=b3d2c131-1225-45b4-9ff5-51ec17511cee

Return data correctly

Spring Security OAUTH2 code procedure

The three core configuration classes that Security OAuth2 integrates

  • 1. ResourceServerConfiguration resource service configuration
  • 2. The authorization service configuration AuthorizationServerConfiguration
  • 3. The security configuration SecurityConfiguration

1. Add maven dependencies to pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.6. RELEASE</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-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.2</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.6.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
Copy the code

Mainly used: Security, OAuth2, Redis, mysql, Mybatis – Plus and other components

2. Certification authorization configuration AuthorizationServerConfigurerAdapter. Java

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    private static final String RESOURCE_IDS = "order";

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    RedisConnectionFactory redisConnectionFactory;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        String finalSecret = "{bcrypt}" + new BCryptPasswordEncoder().encode("123456");
        // Configure two clients, one for password authentication and one for client authentication
        clients.inMemory()

                / / client mode
                .withClient("client_1")
                .resourceIds(RESOURCE_IDS)
                .authorizedGrantTypes("client_credentials"."refresh_token")
                .scopes("select")
                .authorities("oauth2")
                .secret(finalSecret)

                .and()

                // Password mode
                .withClient("client_2")
                .resourceIds(RESOURCE_IDS)
                .authorizedGrantTypes("password"."refresh_token")
                .scopes("select")
                .authorities("oauth2")
                .secret(finalSecret);
    }

    /** * Authentication service endpoint configuration */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                // User management
                .userDetailsService(userDetailsService)
                / / token to redis
                .tokenStore(new RedisTokenStore(redisConnectionFactory))
                // Enable oauth2 management
                .authenticationManager(authenticationManager)
                // Receive GET and POST
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) { oauthServer.allowFormAuthenticationForClients(); }}Copy the code

3. Resource allocation ResourceServerConfig. Java

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    private static final String RESOURCE_IDS = "order";

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(RESOURCE_IDS).stateless(true);
    }

    @Override
    public void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .authorizeRequests()
                .antMatchers("/order/**").authenticated();      // Configure the order access control, must be authenticated before access}}Copy the code

4. Users and permissions to save to the database password mode, UserDetailsServiceImpl. Java


@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserServiceImpl userService;

    /** * Implements the loadUserByUsername method in UserDetailsService to load user data */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.queryUserByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User does not exist");
        }

        // List of user permissions
        Collection<? extends GrantedAuthority> authorities = userService.queryUserAuthorities(user.getId());

        return new AuthUser(
                user.getId(),
                user.getUsername(),
                user.getPassword(),
                true.true.true.true, authorities); }}Copy the code

5. WebSecurityConfig configuration

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    PasswordEncoder passwordEncoder(a) {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

    /** * Inject the AuthenticationManager interface and enable OAuth2 password mode **@return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean(a) throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }

    /** * Implements a custom filtering configuration for Security via HttpSecurity **@param httpSecurity
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .requestMatchers().anyRequest()
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/**").permitAll(); }}Copy the code

6. Application. Yml configuration

server:
  port: 8080

spring:
  thymeleaf:
    encoding: UTF-8
    cache: false

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/easy_web? useSSL=false&serverTimezone=UTC
    username: root
    password: 123456

  redis:
    host: 127.0. 01.
    port: 6379
    password:

logging.level.org.springframework.security: DEBUG
Copy the code

7. Inital. SQL database initialization script

DROP TABLE IF EXISTS `user`;
DROP TABLE IF EXISTS `role`;
DROP TABLE IF EXISTS `user_role`;
DROP TABLE IF EXISTS `role_permission`;
DROP TABLE IF EXISTS `permission`;

CREATE TABLE `user` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL.`password` varchar(255) NOT NULL,
PRIMARY KEY (`id`));CREATE TABLE `role` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`));CREATE TABLE `user_role` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`user_id` bigint(11) NOT NULL.`role_id` bigint(11) NOT NULL,
PRIMARY KEY (`id`));CREATE TABLE `role_permission` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`role_id` bigint(11) NOT NULL.`permission_id` bigint(11) NOT NULL,
PRIMARY KEY (`id`));CREATE TABLE `permission` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`url` varchar(255) NOT NULL.`name` varchar(255) NOT NULL.`description` varchar(255) NULL.`pid` bigint(11) NOT NULL,
PRIMARY KEY (`id`));INSERT INTO user (id, username, password) VALUES (1.'user'.'{bcrypt}$2a$10$Tme77eHtXzcB8ghQUepYguJr7P7ESg0Y7XHMnk60s.kf2A.BWBD9m');
INSERT INTO user (id, username , password) VALUES (2.'admin'.'{bcrypt}$2a$10$Tme77eHtXzcB8ghQUepYguJr7P7ESg0Y7XHMnk60s.kf2A.BWBD9m');
INSERT INTO role (id.name) VALUES (1.'USER');
INSERT INTO role (id.name) VALUES (2.'ADMIN');
INSERT INTO permission (id.url.name, pid) VALUES (1.'/user/common'.'common'.0);
INSERT INTO permission (id.url.name, pid) VALUES (2.'/user/admin'.'admin'.0);
INSERT INTO user_role (user_id, role_id) VALUES (1.1);
INSERT INTO user_role (user_id, role_id) VALUES (2.1);
INSERT INTO user_role (user_id, role_id) VALUES (2.2);
INSERT INTO role_permission (role_id, permission_id) VALUES (1.1);
INSERT INTO role_permission (role_id, permission_id) VALUES (2.1);
INSERT INTO role_permission (role_id, permission_id) VALUES (2.2);
Copy the code

After the above seven steps, we quickly implemented Oauth2 password mode and customer mode functions.

data

  • Example code – Github
  • Ruan Yifeng understands OAuth 2.0