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.
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