@toc OAuth2.0 series blog:
- Basic Concept and Operation Process of OAuth2.0 Series (1)
- OAuth2.0 Authorization Mode Tutorial (part 2)
- OAuth2.0 Simplified Mode Tutorial (Part 3)
- OAuth2.0 Series of Password mode practice tutorial (4)
- OAuth2.0 Client Mode Tutorial (5)
- OAuth2.0 Series information database storage tutorial (6)
- OAuth2.0 Redis Information Storage Tutorial (7)
- OAuth2.0 JWT Token Tutorial (8)
- OAuth2.0 series integrated JWT for single sign-on
1. Introduction to client mode
1.1 Introduction
In the previous article, we learned some basic concepts of OAuth2, gained a basic understanding of OAuth2, and then studied the client mode in the OAuth2.0 authorization mode
Ps: OAuth2.0 authorization mode can be divided into:
- Authorization Code
- Simplified patterns (Implicit)
- Password mode (Resource owner Password Credentials)
- Client credentials
Client credentials: The client credentials mode applies to command line applications without a front end, that is, token requests are made on the command line
1.2 Authorization Flow Chart
Official website photo:
- (A) The client provides client_ID and other information to the authorization server for authentication
- (B) The acceptToken is returned to the client after the authorization is approved
In terms of tuning interface, simply put:
-
Step one: access token http://localhost:8888/oauth/token? client_id=cms&client_secret=secret&grant_type=client_credentials&scope=all
-
Step 2: After receiving acceptToken, you can access the resource directly
http://localhost:8084/api/userinfo?access_token=${accept_token}
2. Examples and practices
2.1 Preparation of the experimental environment
- IntelliJ IDEA
- Maven3.+ Create a SpringBoot Initializer project and name it password
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<! -- Spring Cloud Oauth2-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<! -- Spring Cloud Security-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
Copy the code
2.2 OAuth2.0 role
From the previous study, we know that OAuth2.0 mainly includes the following roles. The following code examples deepen the understanding of the theory
- Resource Owner
- User Agent
- The Client (Client)
- Authorization Server
- Resource Server
Production, resource, and authorization servers are typically kept separate, but learning can be kept together
Define the resource server with the @enableresourceserver annotation; Define authorization server, use annotations @ EnableAuthorizationServer;
2.3 OAuth2.0 configuration class
package com.example.oauth2.clientcredentials.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
/** ** <pre> * OAuth2.0 configuration class * </pre> ** <pre> *@authorMazq * Modified Record * Modified by: Date: 2020/06/11 11:00 Modified Content: * </pre> */
@Configuration
// Enable the authorization service
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
private static final String CLIENT_ID = "cms";
private static final String SECRET_CHAR_SEQUENCE = "{noop}secret";
private static final String SCOPE_READ = "read";
private static final String SCOPE_WRITE = "write";
private static final String TRUST = "trust";
private static final String USER ="user";
private static final String ALL = "all";
private static final int ACCESS_TOKEN_VALIDITY_SECONDS = 2*60;
private static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 2*60;
// Password mode Authorization mode
private static final String GRANT_TYPE_PASSWORD = "password";
// Authorization code mode
private static final String AUTHORIZATION_CODE = "authorization_code";
/ / refresh token mode
private static final String REFRESH_TOKEN = "refresh_token";
// Simplify the authorization mode
private static final String IMPLICIT = "implicit";
// Client mode
private static final String CLIENT_CREDENTIALS="client_credentials";
// Specify which resources require authorization validation
private static final String RESOURCE_ID = "resource_id";
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
// Use memory storage
.inMemory()
// Mark the client ID
.withClient(CLIENT_ID)
// Client security code
.secret(SECRET_CHAR_SEQUENCE)
// Return code for true direct automatic authorization success
.autoApprove(true)
.redirectUris("http://127.0.0.1:8084/cms/login") // Redirect the URI
// Allow the scope of authorization
.scopes(ALL)
/ / token time seconds
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS)
// Refresh the token time in seconds
.refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS)
// Allowed authorization type
.authorizedGrantTypes(CLIENT_CREDENTIALS );
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// Use memory to store the generated token
endpoints.authenticationManager(authenticationManager).tokenStore(memoryTokenStore());
}
/** * Authentication server security configuration **@param security
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
//.realm(RESOURCE_ID)
// Enable /oauth/token_key authentication port permission access
.tokenKeyAccess("isAuthenticated()")
// Enable /oauth/check_token authentication port authentication permission access
.checkTokenAccess("isAuthenticated()")
// Allow form authentication
.allowFormAuthenticationForClients();
}
@Bean
public TokenStore memoryTokenStore(a) {
// The most basic InMemoryTokenStore generates tokens
return newInMemoryTokenStore(); }}Copy the code
2.4 Security Configuration Classes
To test, you can do simple SpringSecurity
package com.example.oauth2.clientcredentials.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/ * * * < pre > * SpringSecurity configuration class * < / pre > < pre > * * *@authorMazq * Modified Record * Modified by: Date: 2020/06/11 11:23 Modified Content: * </pre> */
@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean(a) throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { //auth.inMemoryAuthentication()
auth.inMemoryAuthentication()
.withUser("nicky")
.password("{noop}123")
.roles("admin");
}
@Override
public void configure(WebSecurity web) throws Exception {
// Resolve static resource interception
web.ignoring().antMatchers("/asserts/**");
web.ignoring().antMatchers("/favicon.ico");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http // Configure the login page and allow access
//.formLogin().permitAll()
// Configure Basic login
//.and().httpBasic()
// Configure the logout page
.logout().logoutUrl("/logout").logoutSuccessUrl("/")
// Configure the links to allow access
.and().authorizeRequests().antMatchers("/oauth/**"."/login/**"."/logout/**"."/api/**").permitAll()
// All other requests require authentication
.anyRequest().authenticated()
// Disable cross-domain protection;.and().csrf().disable(); }}Copy the code
2.5 Simple function test
When the response_type parameter is passed to the postman interface, the response_type parameter is passed to the postman interface.
http://localhost:8888/oauth/token?client_id=cms&client_secret=secret&grant_type=client_credentials&scope=all
Username = client_id and password = client_secret
Code request, can be encapsulated as follows, that is, base64 encryption
HttpHeaders headers = new HttpHeaders();
byte[] key = (clientId+":"+clientSecret).getBytes();
String authKey = new String(Base64.encodeBase64(key));
LOG.info("Authorization:{}"."Basic "+authKey);
headers.add("Authorization"."Basic "+authKey);
Copy the code
Get a token to adjust business interface directly: http://localhost:8888/api/userinfo? access_token=61b113f3-f1e2-473e-a6d7-a0264bfdfa8d
Example code download