Spring Security Series (12) - four authorization modes of Oauth2 open platform authorization service

Posted by Haroskyline on Tue, 18 Jan 2022 02:12:57 +0100

to configure

1. Add WebSecurityConfigurerAdapter configuration

A password parser is added, a user is added in memory, and other configurations will be added later.

@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                // Create a user in memory and encrypt the password
                .withUser("user").password(passwordEncoder().encode("123456")).roles("USER");
    }

    // Cipher parser
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

2. Add the AuthorizationServerConfigurerAdapter configuration

AuthorizationServerConfigurerAdapter is the configuration class of the authorization server. Here, an Oauth2 client is configured in memory, and the database storage will be integrated later.

@Configuration
@EnableAuthorizationServer
public class MyAuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {


    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // Configure client
        clients
                // Use memory settings
                .inMemory()
                // client_id
                .withClient("client")
                // client_secret
                .secret(passwordEncoder.encode("secret"))
                // Authorization type: authorization code, refresh token
                .authorizedGrantTypes("authorization_code","refresh_token")
                // Scope of authorization
                .scopes("app")
                // Register callback address
                .redirectUris("http://localhost:20000/code");
    }
}

Default endpoint URL

The default endpoint URL (access interface) is provided, which we need to use when performing Oauth2 authentication.

  • /oauth/authorize: authorize the endpoint.
  • /oauth/token: token endpoint.
  • /oauth/confirm_access: the user confirms the authorization submission endpoint.
  • /oauth/error: authorization service error information endpoint.
  • /oauth/check_token: token resolution endpoint for resource service access.
  • /oauth/token_key: the endpoint that provides the public key, if you use the JWT token.

Four authorization modes

Authorization code mode

First, review the authorization code mode flow. As can be seen from the figure, the following steps are required to obtain a token:

  • The Oauth Client obtains the code through the client's account and password
  • Get token using code
  • Carrying tokens to access resources

1. Obtain authorization code

Access the endpoint that gets the authorization code

http://localhost:20000/oauth/authorize?client_id=client&client_secret=secret&response_type=code

Parameter Description:

parameterexplainRequired
client_idId used to identify the customerYES
client_secret(requires a trusted client) client passwordYES
response_typeThe authorization code mode is fixed to codeYES
redirect_uriJump to uri. When the authorization code application is successful, it will jump to this address with the code parameter (authorization code) in the backNO
scopeIt is used to limit the access range of the client. If it is empty (default), the client has all the access rangesNO
stateRandom values can be taken to prevent CORS attacksNO

Then it will be transferred to the login interface and enter the user name and password

2. Obtain authorization code

After successful login, jump to the authorization page, whether to allow this client to access your resources, select Approve, and click agree to authorize.

After that, the browser will redirect to the configured callback address and carry the authorization code, so the callback address should be the address of the added client server itself.

3. Get token

A Post request is required to access the token endpoint to obtain a token. postman is used here.

Post request access endpoint:

http://localhost:20000/oauth/token

First, the ID and password of the client need to be passed in. The httpBasic authentication method is adopted, and it is spliced into the format of "user name: password", with a colon in the middle, and then base64 is encoded into xxx, and then Authorization:Basic xxx is appended to the request header. Here, you can use postman to select Basic Auth, and then enter the client ID and password.

Add parameters:

Parameter Description:

parameterexplain
codeThe authorization code is the authorization code just obtained. Note: the authorization code is invalid only once and needs to be applied again
grant_typeAuthorization type, fill in authorization_code, indicating authorization code mode
redirect_uriThe jump url when applying for authorization code must be the same as the redirect used when applying for authorization code_ Uri consistent.

Access, get the access and refresh token.

{
    "access_token": "0ce36dcf-79c0-490e-873b-d3e295028b73",
    "token_type": "bearer",
    "refresh_token": "7b67b4b3-87a9-4b40-970d-44598f9cb355",
    "expires_in": 42723,
    "scope": "app"
}

When you click again, an error will be reported, indicating that the code can only be used once.

Password mode

The password mode directly uses the user name and password to obtain the token, which is generally used for home applications.

1. Add authentication manager

As mentioned earlier, spring security uses the authentication manager for login authentication. In Oauth2, you need to configure an endpoint authentication manager to use the user name and password for authentication.

Inject an authentication manager into MyWebSecurityConfiguration:

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

In the myauthorization server configuration configuration configuration authentication manager, add Oauth2 client password mode support.

@Configuration
@EnableAuthorizationServer
public class MyAuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {


    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
     private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // Configure client
        clients
                // Use memory settings
                .inMemory()
                // client_id
                .withClient("client")
                // client_secret
                .secret(passwordEncoder.encode("secret"))
                // Authorization type: authorization code, refresh token, password, client
                .authorizedGrantTypes("authorization_code","refresh_token","password","client_credentials")
                // Scope of authorization
                .scopes("app")
                // Register callback address
                .redirectUris("http://localhost:20000/code");
    }
    // Endpoint Configuration 
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        // Configure the request mode allowed by the endpoint
        endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
        // Configure authentication manager
        endpoints.authenticationManager(authenticationManager);
    }
}

2. Get token

Post request access request endpoint:

http://localhost:20000/oauth/token

Add parameters:

Parameter Description:

parameterexplain
grant_typeAuthorization code type, fixed as password
usernameUser's account
passwordUser's password

Like the authorization code mode, add the authentication message header:

Get the token, click it many times and find that the token we got is the same, but expires_in is changing.

Client mode

In client mode, tokens can be returned directly through the interface.

Access endpoint, grant_type is client_credentials:

http://localhost:20000/oauth/token?grant_type=client_credentials

Add Httpbasic authentication to the message header:

Access return token:

Simplified mode

Implicit mode is also translated into implicit mode or compact mode. Simplification is aimed at simplifying the authorization code mode, and obtaining a token without an authorization code.

The simplified mode can be through the client name and a redirect_uri to access the authentication server. After authentication, the authentication server will directly return a token, which will be returned in redirect_ Use # connections behind URIs.

Client add simplified mode support:

// Authorization type: authorization code, refresh token, password, client, simplified mode
.authorizedGrantTypes("authorization_code","refresh_token","password","client_credentials","implicit")

Access endpoint, mainly response_type is token

http://localhost:20000/oauth/authorize?client_id=client&client_secret=secret&response_type=token

Then log in and authorize, which is consistent with the authorization code mode.

After clicking authorization, the token and expiration time are returned directly through the callback address.

Topics: Java Spring security jwt