Single sign-on (SSO for short), also known as Single check-in, is an attribute that provides access control to many interconnected but independent software systems. With this property, users can gain access to all systems when they log in, rather than logging in to every single system. This capability is typically implemented using the Lightweight Directory Access Protocol (LDAP), where user information is stored in an LDAP database on the server. Similarly, a single sign-off means that access to multiple systems can be terminated with a single sign-off action.

Security OAuth2 Single sign-on process diagram

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/1/25/1612df517b7d9d71~tplv-t2oaga2asx-image.image

  1. Visit client1
  2. client1Redirect requestssso-server
  3. authorize
  4. Carry authorization Codecodereturnclient1
  5. client1Request the token with the authorization code
  6. returnJWTThe token
  7. client1Parse the token and log in
  8. client1accessclient2
  9. client2Redirect requestssso-server
  10. authorize
  11. Carry authorization Codecodereturnclient2
  12. client2Request the token with the authorization code
  13. returnJWTThe token
  14. client2Parse the token and log in

The USER login status is saved by the SSO-server authentication center, and the login interface and account password are verified by the SSO-server authentication center (Client1 and CLIen2 return different tokens, but the resolved user information is the same user).

Security OAuth2 implements single sign-on

The project structure

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/1/25/1612df517b8f34ca~tplv-t2oaga2asx-image.image

sso-server

Authentication server

@Configuration
@EnableAuthorizationServer
public class SsoAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    /** * Some configuration of the client *@param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("merryyou1")
                .secret("merryyousecrect1")
                .authorizedGrantTypes("authorization_code"."refresh_token")
                .scopes("all")
                .and()
                .withClient("merryyou2")
                .secret("merryyousecrect2")
                .authorizedGrantTypes("authorization_code"."refresh_token")
                .scopes("all");
    }

    /** * Configure jwttokenStore *@param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter());
    }

    /** * springSecurity authorization expression that requires authentication to access MerryYou tokenkey *@param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("isAuthenticated()");
    }

    /**
     * JWTtokenStore
     * @return* /
    @Bean
    public TokenStore jwtTokenStore(a) {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /** * Generate JTW token *@return* /
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(a){
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("merryyou");
        returnconverter; }}Copy the code

Security configuration

@Configuration
public class SsoSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin().loginPage("/authentication/require")
                .loginProcessingUrl("/authentication/form")
                .and().authorizeRequests()
                .antMatchers("/authentication/require"."/authentication/form"."/**/*.js"."/**/*.css"."/**/*.jpg"."/**/*.png"."/**/*.woff2"
                )
                .permitAll()
                .anyRequest().authenticated()
                .and()
                .csrf().disable();
// http.formLogin().and().authorizeRequests().anyRequest().authenticated();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); }}Copy the code

SsoUserDetailsService

@Component
public class SsoUserDetailsService implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new User(username, passwordEncoder.encode("123456"), AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); }}Copy the code

application.yml

server:
  port: 8082
  context-path: /uaa
spring:
  freemarker:
    allow-request-override: false
    allow-session-override: false
    cache: true
    charset: UTF-8
    check-template-location: true
    content-type: text/html
    enabled: true
    expose-request-attributes: false
    expose-session-attributes: false
    expose-spring-macro-helpers: true
    prefer-file-system-access: true
    suffix: .ftl
    template-loader-path: classpath:/templates/
Copy the code

sso-client1

SsoClient1Application

@SpringBootApplication
@RestController
@EnableOAuth2Sso
public class SsoClient1Application {

    @GetMapping("/user")
    public Authentication user(Authentication user) {
        return user;
    }

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

application.yml

Auth - server: http://localhost:8082/uaa # sso - server address server: context - path: / client1 port: 8083 security: oauth2: client: client-id: merryyou1 client-secret: merryyousecrect1 user-authorization-uri: ${auth-server}/oauth/authorize # Authorize address Access-tok-URI: ${auth-server}/oauth/token # Request token address resource: JWT: key-uri: ${auth-server}/oauth/token # Request token address ${auth-server}/oauth/token_key # Address of key needed to parse JWT tokenCopy the code

sso-client2

With the sso – client1 is consistent

The effect is as follows:

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/1/25/1612df517b92112f~tplv-t2oaga2asx-image.image

The code download

Download it from my Github, github.com/longfeizhen…