Oauth2.0 and spring implementation

Time:2021-1-25

1、 What is oauth2.0

Quote Baidu’s explanation:

OAuth 2.0 is a continuation of OAuth protocol, but it is not forward compatible with OAuth 1.0 (that is, it completely abolished OAuth 1.0). OAuth 2.0 focuses on the simplicity of client developers. Either the approved interaction between the resource owner and the HTTP service provider is used to represent the user, or the third-party application is allowed to obtain access rights on behalf of the user. At the same time for web applications, desktop applications and mobile phones, and living room equipment to provide special authentication process. In October 2012, OAuth 2.0 protocol was officially released as RFC 6749

Baidu Encyclopedia

To put it simply, it is used for authentication.

2、 What scenarios need to use oauth2.0

Generally speaking, we need to be open-mindedThird partyWe need to use authentication when we open the system to the third party. Generally speaking, we don’t need to use the internal system because we usually have our own user center or login center. These systems can be used for authentication. Why do we need authentication when we open the system to the third party? There are mainly the following reasons:

1. Safety

Internal call user center, mailbox, mobile phone number and other information can generally be obtained, but when it is open to the third party, we need to do a good job in security processing, in order to prevent the third party from causing personal data leakage and other problems.

2. Reuse

If each system needs to implement a set of authentication process, the interaction efficiency of the system is too low, so there will be a set of unified authentication process to interact with the third party. Generally speaking, these are used more in the gateway.

Interested can see how to integrate QQ login, its implementation is to follow the oauth2.0 standard.

3、 Process and concept of oauth2.0

Before introducing the process, let’s take a scenario, if there is a social networking site www.xxx.com If you want to integrate QQ login, users will store their personal data after they register on social networking sites, and log in through www.xx.com/personal We can access the user’s Avatar and other information (the actual URL may belong to the gateway), and we also ignore the details such as parameters.

1. Oauth2.0 role

There are the following types of roles:

A、Client

Some are also called third-party applications, which refer to applications that want to integrate resource access.

It’s a bit of a twist. Take the example above www.xxx.com It means client.

B、Resource Owner

Resource owner, generally refers to the user;

Because we need to access the user’s email and mobile phone number information, which belongs to the user and requires the consent of the user, so the user is the resource owner.

C、User Agent

User agent refers to the browser.

D、Authorization server

Authentication server, that is, the server used by service provider to deal with authentication.

E、Resource server

The resource server is the server where the service provider stores the user generated resources.

Back to the example above, if we want to access the user’s mailbox, that is, through the www.xxx.com/personal This interface gets the resource server www.xxx.com Server.

It can be deployed on the same server as the authentication server or on different servers.

2. Several modes of oauth2.0

A. Authorization code grant

Paste the official picture

Oauth2.0 and spring implementation

The steps are as follows:

(1) The user accesses the client, that is www.xxx.com The latter directs the former to the authentication server, i.e graph.qq.com/oauth2 .0/show;

(B) The user chooses whether to grant authorization to the client;

(C) Assuming that the user gives authorization, the authentication server will direct the user to the “redirection URI” specified by the client in advance, and attach an authorization code.

(D) The client receives the authorization code, attaches the previous “redirection URI” and applies for a token from the authentication server. This step is done on the server in the background of the client, which is invisible to the user.

(E) After checking the authorization code and redirection URI, the authentication server sends the request of access token and refresh token to the client.

B. Implicit grant

Oauth2.0 and spring implementation

Compared with the authorization code mode, the difference is that there is no step to obtain the authorization code.

C. Resource owner password credentials grant
Oauth2.0 and spring implementation

(1) User to client( www.xxx.com )Provide a user name and password.

(2) Client( www.xxx.com )Send the user name and password to the authentication server( open.qq.com ), to request a token from the latter.

(3) After the authentication server confirms that there is no error, it provides the access token to the client.

D. Client credentials

Oauth2.0 and spring implementation

This is the simplest mode. As long as the client requests, the www.xxx.com When the background task initiates a request, we send the accesstoken to it.

4、 Spring implementation

Because of the space, we don’t plan to write too much code. Let’s run the process with a small demo.

Create a spring BOT project in idea. Pay attention to spring web and spring security,

New authentication server code

@Configuration
@EnableAuthorizationServer
public class ConfigAdapter extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private DataSource myDataSource;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        super.configure(security);
    }

    @Bean
    public TokenStore tokenStore() {
        return new InMemoryTokenStore();
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    /**
     *Data sources
     * @return
     */
    public DataSource dataSource(){
        return myDataSource;
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client-id")
                .secret("client-secret")
                .scopes("read", "write")
                .authorizedGrantTypes("password", "refresh_ token", "code", "authorization_ "// corresponding response_ Do you have permission
                .redirectUris("http://www.baidu.com")
                .authorities("user:view");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager)
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
    }

}

Then add the authentication logic. First, write it down

public class MyAuthenticationManager implements AuthenticationManager {

    /*
        Authorization process
     */
    public Authentication authenticate(Authentication authentication) throws AuthenticationException{
        String userName, password;

        userName = (String)authentication.getPrincipal();
        password = (String)authentication.getCredentials();

        if ((userName == "edward") && (password == "123")){
            Authentication res = new UsernamePasswordAuthenticationToken(authentication.getPrincipal()
                    , authentication.getPrincipal());
            return res;
        }

        return null;
    }
}

To configure user information, write it first

@Configuration
@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    MyAuthenticationProvider myAuthenticationProvider() {
        return new MyAuthenticationProvider();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("edward").password("123").authorities("USER")
                .and()
                .withUser("user_2").password("123456").authorities("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        //http.regexMatcher("/image/.+").authorizeRequests().anyRequest().authenticated();
        http.authorizeRequests().antMatchers("/post/**", "/oauth/**", "/login/**").permitAll()
                .anyRequest().authenticated()
                .and().formLogin().permitAll()
        ;
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }

    @Bean
    @Override
    protected UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("edward").password("123").authorities("USER").build());
        manager.createUser(User.withUsername("user_2").password("123456").authorities("USER").build());
        return manager;
    }

}

Add a new controller, which represents our resources to be protected

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("hello")
    public String hello(){
        return "hello user";
    }
}

Then access several URLs of authorization code mode in the browser:

1. Get token

http://localhost:8080/oauth/authorize?response_type=code&client_id=client-id&redirect_uri=http://www.baidu.com

2. Get the token according to the code

http://localhost:8080/oauth/token?grant_type=authorization_code&code=Dx5tnU&client_id=client-id&client_secret=client-secret&redirect_uri=http://www.baidu.com

This step will jump to www.baidu.com And returns an accesstoken

3. Access resources according to accesstoken

http://localhost:8080/user/hello?accessToken=123

You need to log in and enter the account and password defined above

edward

123

If you want to keep your eyes on new and interesting technologies, please pay attention to my official account.

Oauth2.0 and spring implementation