Getting started with Spring Cloud components -- Security

brief introduction

Spring Cloud Security provides a series of solutions for building secure spring boot applications. Combining with Oauth2, it can realize functions such as single sign on, token relay and token exchange. OAuth 2.0 is an industry standard protocol for authorization. OAuth 2.0 provides specific authorization flow for simplifying client development, including Web applications, desktop applications, mobile applications, etc.

Explanation of OAuth2 related terms

Resource owner: the end user who owns the resource, who has the account password to access the resource;
Resource server: a server with protected resources. If the request contains the correct access token, the resource can be accessed;
Client: the client that accesses the resource will use the access token to obtain the resource of the resource server, which can be a browser, mobile device or server;
Authorization server: the server used to authenticate users. If the client passes the authentication, it will issue a token to access the resource server.

Four authorization modes

Authorization Code mode: the authentic authorization mode of OAuth2. The client first directs the user to the authentication server, logs in, obtains the Authorization Code, then authorizes, and finally obtains the access token according to the Authorization Code;
Implicit (simplified mode): compared with authorization code mode, it cancels the process of obtaining authorization code and directly obtains access token;
Resource Owner Password Credentials: the client obtains the user name and password directly from the user, and then obtains the access token from the authentication server;
Client Credentials: clients directly pass client authentication (such as client_id and client_secret) gets the access token from the authentication server.

Use of Oauth2

Source address (case uses authorization code mode)

Oauth2 server creation

1. Introduce dependency

		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2. Modify configuration

server:
  port: 9401
spring:
  application:
    name: oauth2-service

3. Add UserService to implement the UserDetailsService interface to load user information:

@Service
public class UserService implements UserDetailsService {
    private List<User> userList;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @PostConstruct
    public void initData() {
        String password = passwordEncoder.encode("123456");
        userList = new ArrayList<>();
        userList.add(new User("macro", password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin")));
        userList.add(new User("andy", password, AuthorityUtils.commaSeparatedStringToAuthorityList("client")));
        userList.add(new User("mark", password, AuthorityUtils.commaSeparatedStringToAuthorityList("client")));
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<User> findUserList = userList.stream().filter(user -> user.getUsername().equals(username)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(findUserList)) {
            return findUserList.get(0);
        } else {
            throw new UsernameNotFoundException("Wrong user name or password");
        }
    }
}

4. Add authentication server configuration and use @ EnableAuthorizationServer annotation to enable

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserService userService;

    /**
     * Using password mode requires configuration
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userService);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("admin")//Configure client_id
                .secret(passwordEncoder.encode("admin123456"))//Configure client_secret
                .accessTokenValiditySeconds(3600)//Configure the validity of the access token
                .refreshTokenValiditySeconds(864000)//Configure the validity of the refresh token
                .redirectUris("http://www.baidu.com")//Configure redirect_uri, used to jump after authorization succeeds
                .scopes("all")//Configure the permission range of the application
                .authorizedGrantTypes("authorization_code","password");//Configure grant_type, indicating authorization type
    }
}

5. Add resource server configuration and use @ EnableResourceServer annotation to enable:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .requestMatchers()
                .antMatchers("/user/**");//Configure resource paths to be protected
    }
}

6. Add the spring security configuration to allow access to authentication related paths and form login:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

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

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf()
                .disable()
                .authorizeRequests()
                .antMatchers("/oauth/**", "/login/**", "/logout/**")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .permitAll();
    }
}

7. Add the interface that the controller needs to log in to test:

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping("/getCurrentUser")
    public Object getCurrentUser(Authentication authentication) {
        return authentication.getPrincipal();
    }
}

verification:

Use authorization code mode
Start oauth2 server service;
Access the address in the browser for login authorization: http://localhost:9401/oauth/authorize?response_type=code&client_id=admin&redirect_uri=http://www.baidu.com&scope=all&state=normal
Enter the account password to log in:


After the authorization is approved, you can jump to the specified webpage and obtain the authorization code

https://www.baidu.com/?code=CHE5wl&state=normal

Use authorization code to request the address to obtain access token: http://localhost:9401/oauth/token

Next, use postman to test and verify:


Project reference: https://juejin.im/post/5dc013bae51d456e817cec30

Tags: Spring Mobile

Posted on Sat, 20 Jun 2020 23:53:27 -0400 by harinath