• SpringCloud搭建微服务之OAuth2实现SSO单点登录


    SSO单点登录实现方式有多种,在这里不介绍理论,本文只讨论采用spring-security-oauth2来实现,本文共有三个服务,一个权限认证中心,两个客户端

    1. 认证服务搭建

    1.1. 引入核心依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.security.oauthgroupId>
        <artifactId>spring-security-oauth2artifactId>
        <version>2.3.8.RELEASEversion>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1.2. 配置application.yml文件

    server:
      port: 8830
      servlet:
        context-path: /auth
    spring:
      application:
        name: cloud-oss-authorization-server
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.3. 编写主启动类

    @EnableResourceServer
    @SpringBootApplication
    public class OssAuthorizationServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(OssAuthorizationServerApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    可以将Authorization Server和Resource Server放在同一个服务里

    1.4. 编写SecurityConfig配置类

    @Order(1)
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                    .withUser("admin")
                    .password(passwordEncoder().encode("123456"))
                    .roles("USER");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.requestMatchers()
                    .antMatchers("/login", "/oauth/authorize")
                    .and()
                    .authorizeRequests()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .formLogin()
                    .permitAll()
                    .and().csrf().disable();
        }
    
        @Bean
        public BCryptPasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    1.5. 编写AuthorizationServerConfig配置类

    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        private BCryptPasswordEncoder passwordEncoder;
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            security.tokenKeyAccess("permitAll()")
                    .checkTokenAccess("isAuthenticated()");
        }
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                    .withClient("SampleClientId")
                    .secret(passwordEncoder.encode("secret"))
                    .authorizedGrantTypes("authorization_code")
                    .scopes("user_info")
                    .autoApprove(true)
                    .redirectUris("http://localhost:8831/ui1/login", "http://localhost:8832/ui2/login");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    1.6. 编写UserController类

    @RestController
    public class UserController {
    
        @RequestMapping(value = "/user/me")
        public Principal user(Principal principal) {
            System.out.println(principal);
            return principal;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2. 客户端服务搭建

    分别新建两个客户端微服务8831和8832

    2.1. 引入核心依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-securityartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.security.oauth.bootgroupId>
        <artifactId>spring-security-oauth2-autoconfigureartifactId>
    dependency>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-thymeleafartifactId>
    dependency>
    <dependency>
        <groupId>org.thymeleaf.extrasgroupId>
        <artifactId>thymeleaf-extras-springsecurity5artifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.2. 配置application.yml文件

    server:
      port: 8831 #另一个服务端口8832
      servlet:
        context-path: /ui1 #另一个服务路径/ui2
        register-default-servlet: true
        session:
          cookie:
            name: UISESSION1 #另一个服务cookie nameUISESSION2
    spring:
      application:
        name: cloud-sso-client8831 #另一个服务名称cloud-sso-client8832
      thymeleaf:
        cache: false
    security:
      basic:
        enabled: false
      oauth2:
        client:
          client-id: SampleClientId
          client-secret: secret
          access-token-uri: http://localhost:8830/auth/oauth/token
          user-authorization-uri: http://localhost:8830/auth/oauth/authorize
        resource:
          user-info-uri: http://localhost:8830/auth/user/me
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2.3. 编写服务启动类

    @SpringBootApplication
    public class OssClientApplication extends SpringBootServletInitializer {
    
        @Bean
        public RequestContextListener requestContextListener() {
            return new RequestContextListener();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(OssClientApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.4. 编写SecurityConfig配置类

    @Configuration
    @EnableOAuth2Sso
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/**")
                    .authorizeRequests()
                    .antMatchers("/", "/login/**")
                    .permitAll()
                    .anyRequest()
                    .authenticated();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.5. 编写WebConfig配置类

    @EnableWebMvc
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
            return new PropertySourcesPlaceholderConfigurer();
        }
    
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/")
                    .setViewName("forward:/index");
            registry.addViewController("/index");
            registry.addViewController("/securedPage");
        }
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/resources/**")
                    .addResourceLocations("/resources/");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2.6. 编写登录页面index.html

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Spring Security SSO Client 1title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
    head>
    <body>
    <div class="container">
        <div class="col-sm-12">
            <h1>Spring Security SSO Client 1h1>
            <a class="btn btn-primary" href="securedPage">Logina>
        div>
    div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.7. 编写登录后跳转页

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Spring Security SSOtitle>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
    head>
    
    <body>
    <div class="container">
        <div class="col-sm-12">
            <h1>Secured Pageh1>
            Welcome, <span th:text="${#authentication.name}">Namespan>
        div>
    div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3. 验证

    依次启动三个微服务cloud-oss-authorization-server、cloud-sso-client8831和cloud-sso-client8832
    浏览器地址栏输入http://localhost:8831/ui1/
    登录页
    点击Login进入单点登录页
    登录
    输入用户名和密码admin/123456
    跳转后页面

  • 相关阅读:
    计算机网络:随机访问介质访问控制之ALOHA协议
    pip安装依赖报错
    03【Spring AOP、CGBLIB代理】
    13、Java 继承的内存布局(图文分析)
    机器学习 day38(有放回抽样、随机森林算法、XGBoost)
    CListCtrl设置只显示单列
    使用Python抢购商品
    千挂科技与东风柳汽达成前装量产合作,2024年交付自动驾驶牵引车
    线性判别分析(机器学习)
    jacoco的学习以及理解
  • 原文地址:https://blog.csdn.net/liu320yj/article/details/128079695