zoukankan      html  css  js  c++  java
  • Spring Cloud下基于OAUTH2认证授权的实现

     

    GitHub(spring -boot 2.0.0):https://github.com/bigben0123/uaa-zuul
    示例(spring -boot 2.0.0): https://github.com/bigben0123/sample-spring-oauth2-microservices (讲解:https://piotrminkowski.wordpress.com/2017/12/01/part-2-microservices-security-with-oauth2/)

     

     

    Spring Cloud需要使用OAUTH2来实现多个微服务的统一认证授权,通过向OAUTH服务发送某个类型的grant type进行集中认证和授权,从而获得access_token,而这个token是受其他微服务信任的,我们在后续的访问可以通过access_token来进行,从而实现了微服务的统一认证授权。

     格式正常地址:Spring Cloud下基于OAUTH2认证授权的实现包含源码

    本示例提供了四大部分:

    • discovery-service:服务注册和发现的基本模块
    • auth-server:OAUTH2认证授权中心
    • order-service:普通微服务,用来验证认证和授权
    • api-gateway:边界网关(所有微服务都在它之后)

    OAUTH2中的角色:

    • Resource Server:被授权访问的资源
    • Authotization Server:OAUTH2认证授权中心
    • Resource Owner: 用户
    • Client:使用API的客户端(如Android 、IOS、web app)

    Grant Type:

    • Authorization Code:用在服务端应用之间
    • Implicit:用在移动app或者web app(这些app是在用户的设备上的,如在手机上调起微信来进行认证授权)
    • Resource Owner Password Credentials(password):应用直接都是受信任的(都是由一家公司开发的,本例子使用)
    • Client Credentials:用在应用API访问。

    1.基础环境

    使用Postgres作为账户存储,Redis作为Token存储,使用docker-compose在服务器上启动PostgresRedis

    Redis:
      image: sameersbn/redis:latest
      ports:
        - "6379:6379"
      volumes:
        - /srv/docker/redis:/var/lib/redis:Z
      restart: always
    
    PostgreSQL:
      restart: always
      image: sameersbn/postgresql:9.6-2
      ports:
        - "5432:5432"
      environment:
        - DEBUG=false
    
        - DB_USER=wang
        - DB_PASS=yunfei
        - DB_NAME=order
      volumes:
        - /srv/docker/postgresql:/var/lib/postgresql:Z
    

    2.auth-server

    2.1 OAuth2服务配置

    Redis用来存储token,服务重启后,无需重新获取token.

    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
        @Autowired
        private AuthenticationManager authenticationManager;
        @Autowired
        private RedisConnectionFactory connectionFactory;
    
    
        @Bean
        public RedisTokenStore tokenStore() {
            return new RedisTokenStore(connectionFactory);
        }
    
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints
                    .authenticationManager(authenticationManager)
                    .tokenStore(tokenStore());
        }
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            security
                    .tokenKeyAccess("permitAll()")
                    .checkTokenAccess("isAuthenticated()");
        }
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                    .withClient("android")
                    .scopes("xx") //此处的scopes是无用的,可以随意设置
                    .secret("android")
                    .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .and()
                    .withClient("webapp")
                    .scopes("xx")
                    .authorizedGrantTypes("implicit");
        }
    }
    
    
    

    2.2 Resource服务配置

    auth-server提供user信息,所以auth-server也是一个Resource Server

    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                    .csrf().disable()
                    .exceptionHandling()
                    .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
                .and()
                    .authorizeRequests()
                    .anyRequest().authenticated()
                .and()
                    .httpBasic();
        }
    }
    
    
    @RestController
    public class UserController {
    
        @GetMapping("/user")
        public Principal user(Principal user){
            return user;
        }
    }
    
    

    2.3 安全配置

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    
        @Bean
        public UserDetailsService userDetailsService(){
            return new DomainUserDetailsService();
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
                    .userDetailsService(userDetailsService())
                    .passwordEncoder(passwordEncoder());
        }
    
        @Bean
        public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
            return new SecurityEvaluationContextExtension();
        }
    
        //不定义没有password grant_type
        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
    
    
    }
    

    2.4 权限设计

    采用用户(SysUser) 角色(SysRole) 权限(SysAuthotity)设置,彼此之间的关系是多对多。通过DomainUserDetailsService 加载用户和权限。

    2.5 配置

    spring:
      profiles:
        active: ${SPRING_PROFILES_ACTIVE:dev}
      application:
          name: auth-server
    
      jpa:
        open-in-view: true
        database: POSTGRESQL
        show-sql: true
        hibernate:
          ddl-auto: update
      datasource:
        platform: postgres
        url: jdbc:postgresql://192.168.1.140:5432/auth
        username: wang
        password: yunfei
        driver-class-name: org.postgresql.Driver
      redis:
        host: 192.168.1.140
    
    server:
      port: 9999
    
    
    eureka:
      client:
        serviceUrl:
          defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
    
    
    
    logging.level.org.springframework.security: DEBUG
    
    logging.leve.org.springframework: DEBUG
    
    ##很重要
    security:
      oauth2:
        resource:
          filter-order: 3
    

    2.6 测试数据

    data.sql里初始化了两个用户admin->ROLE_ADMIN->query_demo,wyf->ROLE_USER

    3.order-service

    3.1 Resource服务配置

    @Configuration
    @EnableResourceServer
    public class ResourceServerConfig  extends ResourceServerConfigurerAdapter{
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                    .csrf().disable()
                    .exceptionHandling()
                    .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
                .and()
                    .authorizeRequests()
                    .anyRequest().authenticated()
                .and()
                    .httpBasic();
        }
    }
    
    

    3.2 用户信息配置

    order-service是一个简单的微服务,使用auth-server进行认证授权,在它的配置文件指定用户信息在auth-server的地址即可:

    security:
      oauth2:
        resource:
          id: order-service
          user-info-uri: http://localhost:8080/uaa/user
          prefer-token-info: false
    

    3.3 权限测试控制器

    具备authorityquery-demo的才能访问,即为admin用户

    @RestController
    public class DemoController {
        @GetMapping("/demo")
        @PreAuthorize("hasAuthority('query-demo')")
        public String getDemo(){
            return "good";
        }
    }
    
    

    4 api-gateway

    api-gateway在本例中有2个作用:

    • 本身作为一个client,使用implicit
    • 作为外部app访问的方向代理

    4.1 关闭csrf并开启Oauth2 client支持

    @Configuration
    @EnableOAuth2Sso
    public class SecurityConfig extends WebSecurityConfigurerAdapter{
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http.csrf().disable();
    
        }
    
    }
    

    4.2 配置

    zuul:
      routes:
        uaa:
          path: /uaa/**
          sensitiveHeaders:
          serviceId: auth-server
        order:
          path: /order/**
          sensitiveHeaders:
          serviceId: order-service
      add-proxy-headers: true
    
    security:
      oauth2:
        client:
          access-token-uri: http://localhost:8080/uaa/oauth/token
          user-authorization-uri: http://localhost:8080/uaa/oauth/authorize
          client-id: webapp
        resource:
          user-info-uri: http://localhost:8080/uaa/user
          prefer-token-info: false


    http://www.360doc.com/content/17/0728/14/16915_674776055.shtml

     
  • 相关阅读:
    IO模型
    协程
    线程
    进程总结
    HashMap和Hashtable有什么区别
    HashMap 1.7 与 1.8 的 区别,说明 1.8 做了哪些优化,如何优化的
    GC线程是否为守护线程?
    float f=3.4;是否正确?
    final、finally和finalized的区别?
    Eureka注册中心是什么?
  • 原文地址:https://www.cnblogs.com/bigben0123/p/9207825.html
Copyright © 2011-2022 走看看