Spring Security OAuth2 SSO 单点登录

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fooelliot/article/details/83617941

基于 Spring Security OAuth2 SSO 单点登录系统

SSO简介

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一退出(single sign-off)就是指,只需要单一的退出动作,就可以结束对于多个系统的访问权限。

Spring Security OAuth

Spring Security OAuth使用标准的Spring和Spring Security编程模型和配置惯例,为使用Spring Security with OAuth(1a)和OAuth2提供支持。OAuth协议

案例介绍

此工程分为三个模块:授权服务器(sso-auth-server)、web应用a(sso-client-a)、web应用b(sso-client-b),想达到的目的是:某一个用户在a系统登陆后在跳往b系统后不用在重复登录。

  • sso-auth-server:

    • pom:
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
        </dependency>
    </dependencies>
    
    • yml:
    server:
      port: 8082
      context-path: /auth_server
    
    • SsoServerApplication.java
    /**
     * @author Leone
     * @since 2018-05-07
     **/
    @SpringBootApplication
    public class SsoServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SsoServerApplication.class, args);
        }
    
        /**
         * 为测试环境添加相关的 Request Dumper information,便于调试
         *
         * @return
         */
        @Profile("!cloud")
        @Bean
        RequestDumperFilter requestDumperFilter() {
            return new RequestDumperFilter();
        }
    
    }
    
    • userDetailsService.java
    /**
     * @author Leone
     * @since 2018-05-07
     **/
    @Component
    public class SsoUserDetailsService implements UserDetailsService {
    
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            return new User(username, passwordEncoder.encode("admin"), AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER"));
        }
    }
    
    • SsoSecurityConfig.java
    /**
     * @author Leone
     * @since 2018-05-07
     **/
    @Configuration
    public class SsoSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private UserDetailsService userDetailsService;
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.formLogin()
                    .and().authorizeRequests()
                    .antMatchers("/**/*.js", "/**/*.css", "/**/*.jpg", "/**/*.png")
                    .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());
        }
    }
    
    • SsoAuthServerConfig.java
    /**
     * @author Leone
     * @since 2018-05-07
     **/
    @Configuration
    @EnableAuthorizationServer
    public class SsoAuthServerConfig extends AuthorizationServerConfigurerAdapter {
    
        /**
         * 客户端一些配置
         *
         * @param clients
         * @throws Exception
         */
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                    .withClient("client1")
                    .secret("secret1")
                    .authorizedGrantTypes("authorization_code", "refresh_token")
                    .scopes("all", "read", "write")
                    .autoApprove(true)
                    .and()
                    .withClient("client2")
                    .secret("secret2")
                    .authorizedGrantTypes("authorization_code", "refresh_token")
                    .scopes("all", "read", "write")
                    .autoApprove(true);
        }
    
        /**
         * 配置jwtTokenStore
         *
         * @param endpoints
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter());
        }
    
        /**
         * springSecurity 授权表达式
         *
         * @param security
         * @throws Exception
         */
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            security.tokenKeyAccess("isAuthenticated()");
        }
    
        /**
         * JwtTokenStore
         *
         * @return
         */
        @Bean
        public TokenStore jwtTokenStore() {
            return new JwtTokenStore(jwtAccessTokenConverter());
        }
    
        /**
         * 生成JTW token
         *
         * @return
         */
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
            converter.setSigningKey("andy");
            return converter;
        }
    }
    
  • sso-client-a

    • pom:
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
        </dependency>
    
    </dependencies>
    
    • yml:
    server:
      port: 8080
      context-path: /clienta
    security:
      oauth2:
        client:
          clientId: client1
          clientSecret: secret1
          access-token-uri: http://127.0.0.1:8082/auth_server/oauth/token    #请求令牌的地址
          user-authorization-uri: http://127.0.0.1:8082/auth_server/oauth/authorize    #请求认证的地址
        resource:
          jwt:
            key-uri: http://127.0.0.1:8082/auth_server/oauth/token_key   #解析jwt令牌所需要密钥的地址
    
    
    • index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>sso-client-A</title>
    </head>
    <body>
        <h1>sso demo client-A</h1>
        <a href="http://127.0.0.1:8081/clientb/index.html">访问client-b</a>
    </body>
    </html>
    
    • SsoClientA.java
    /**
     * @author Leone
     * @since 2018-05-07
     **/
    @EnableOAuth2Sso
    @SpringBootApplication
    public class SsoClientA {
        public static void main(String[] args) {
            SpringApplication.run(SsoClientA.class, args);
        }
    }
    
  • sso-client-b

    • pom:
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
        </dependency>
    
    </dependencies>
    
    • yml:
    server:
      port: 8081
      context-path: /clientb
    security:
      oauth2:
        client:
          clientId: client2
          clientSecret: secret2
          access-token-uri: http://127.0.0.1:8082/auth_server/oauth/token
          user-authorization-uri: http://127.0.0.1:8082/auth_server/oauth/authorize
        resource:
          jwt:
            key-uri: http://127.0.0.1:8082/auth_server/oauth/token_key
    
    
    • index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>sso-client-B</title>
    </head>
    <body>
        <h1>sso demo client-B</h1>
        <a href="http://127.0.0.1:8080/clienta/index.html">访问client-a</a>
    </body>
    </html>
    
    • SsoClientA.java
    /**
     * @author Leone
     * @since 2018-05-07
     **/
    @RestController
    @EnableOAuth2Sso
    @SpringBootApplication
    public class SsoClientB {
    
        @Autowired
        private OAuth2RestTemplate oAuth2RestTemplate;
    
        public static void main(String[] args) {
            SpringApplication.run(SsoClientB.class, args);
        }
    
        @GetMapping("/user")
        public Authentication user(Authentication user) {
            return user;
        }
    
        @Bean
        public OAuth2RestTemplate oAuth2RestTemplate(OAuth2ClientContext oAuth2ClientContext, OAuth2ProtectedResourceDetails details){
            return new OAuth2RestTemplate(details,oAuth2ClientContext);
        }
    }
    

项目源码:[email protected]:janlle/sso-server.git

猜你喜欢

转载自blog.csdn.net/fooelliot/article/details/83617941