What is the OAuth2

OAuth (Open Authorization) is an open standard that allows users to authorize third party mobile applications to access their information stored on another service provider without having to provide a user name and password to third party mobile applications or share all content of their data. OAuth2.0 is a continuation of the OAuth protocol.

Authorization server code

pom

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2. RELEASE</version>
        <relativePath/> <! -- lookup parent from repository -->
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <! -- Spring Security OAuth2 -->
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.4.0. RELEASE</version>
        </dependency>
    </dependencies>
Copy the code

Start the class

@SpringBootApplication
public class App {
    public static void main(String[] args) { SpringApplication.run(App.class, args); }}Copy the code

Populated UserDetails login

package com.service;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
        GrantedAuthority grantedAuthority = null;
        if(username.equals("name1")){
            grantedAuthority = new SimpleGrantedAuthority("name1");
        }else if(username.equals("name2")){
            grantedAuthority = new SimpleGrantedAuthority("name2");
        }else if(username.equals("name3")){
            grantedAuthority = new SimpleGrantedAuthority("name3");
        }else if(username.equals("name4")){
            grantedAuthority = new SimpleGrantedAuthority("name4");
        }else if(username.equals("name5")){
            grantedAuthority = new SimpleGrantedAuthority("name5");
        }else if(username.equals("name6")){
            grantedAuthority = new SimpleGrantedAuthority("name6");
        }
        grantedAuthorities.add(grantedAuthority);
        return new User(username, new BCryptPasswordEncoder().encode("123456"), grantedAuthorities); }}Copy the code

config

WebSecurityConfiguration

package com.config;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Resource
    UserDetailsServiceImpl userDetailsService;
    @Bean
    public BCryptPasswordEncoder passwordEncoder(a) {
        // Set the default encryption mode
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }
    @Override
    public void configure(WebSecurity web) throws Exception {
        // Expose check_token, otherwise the resource server will report 403
        web.ignoring().antMatchers("/oauth/check_token"); }}Copy the code

AuthorizationServerConfiguration

package com.config;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    // Inject the BCryptPasswordEncoder configured in WebSecurityConfiguration
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients
                .inMemory()
                .withClient("client")
                // You also need to encrypt secret
                .secret(passwordEncoder.encode("secret"))
                .authorizedGrantTypes("authorization_code")
                .scopes("app")
               //. AutoApprove (true)// Automatic authorization
                .redirectUris("http://localhost:8082/getcode"); }}Copy the code

Access code

A get request

http://localhost:8080/oauth/authorize?client_id=client&response_type=code

Access token

A post request

http://client:secret@localhost:8080/oauth/token?grant_type=authorization_code&code=XYZJNL

Alternatively, you can start the token acquisition server to obtain the token directly before login

Resource server code

pom

Same as above

Start the class

Same as above

ResourceServerConfiguration

package com.config;
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    @Primary
    @Bean
    public RemoteTokenServices remoteTokenServices(a) {
        final RemoteTokenServices tokenServices = new RemoteTokenServices();
        // Set the authorization server check_token endpoint full address
        tokenServices.
                setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");
        // Set client ID and secret. Note: Client_secret cannot be encrypted using passwordEncoder!
        tokenServices.setClientId("client");
        tokenServices.setClientSecret("secret");
        return tokenServices;
    }
    @Override
    public void configure(HttpSecurity http) throws Exception {
            http
                .exceptionHandling()
                .and()
                .sessionManagement().sessionCreationPolicy
                    (SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // The following are the resource paths and permissions to be protected. They must correspond to the authorization part configured on the authentication server
                .antMatchers("/name1/**").hasAuthority("name1")
                .antMatchers("/name2/**").hasAuthority("name2")
                .antMatchers("/name3/**").hasAuthority("name3")
                .antMatchers("/name4/**").hasAuthority("name4")
                .antMatchers("/name5/**").hasAuthority("name5")
                .antMatchers("/name6/**").hasAuthority("name6"); }}Copy the code

controller

package com.controller;
@RestController
public class UserController {
    @RequestMapping("/name1")
    public String name1(a){
        Authentication authentication = 
            SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        return "Username:"+principal.toString();
    }
    @RequestMapping("/name2")
    public String name2(a){
        return "name2";
    }
    @RequestMapping("/name3")
    public String name3(a){
        return "name3";
    }
    @RequestMapping("/name4")
    public String name4(a){
        return "name4";
    }
    @RequestMapping("/name5")
    public String name5(a){
        return "name5";
    }
    @RequestMapping("/name6")
    public String name6(a){
        return "name6"; }}Copy the code

application.yml

server:
  port: 8081
logging:
  level:
    root: INFO
    org.springframework.web: INFO
    org.springframework.security: INFO
    org.springframework.security.oauth2: INFO
Copy the code

Access to the resource

Either GET or POST works

http://localhost:8081/name1?access_token=60de7fb7-6511-4a18-808b-04c3ab6b53c6

You can also add something like this to the header:

‘Authorization’: ‘e9ca9dcf-12bc-4e25-8831-afd69d4760ec’

Get the token server code

Pom app ditto

package com.controller;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.support.BasicAuthorizationInterceptor;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class TokenController {
    @RequestMapping("/getcode")
    public  String getCode(String code){
        RestTemplate restTemplate = new RestTemplate();
        // Request address client:secret@
        String url = "http://localhost:8080/oauth/token";
        restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("client"."secret"));
        // Request header Settings,x-www-form-urlencoded data
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // Submit parameter Settings
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("grant_type"."authorization_code");
        map.add("code",code);
        // Assemble the request body
        HttpEntity<MultiValueMap<String, String>> request =
                new HttpEntity<MultiValueMap<String, String>>(map, headers);
        // Send the POST request, print the result, and receive the result as a String JSON String
        String tokenjson = restTemplate.postForObject(url, request, String.class);
        returntokenjson; }}Copy the code