springboot2整合oauth2实现密码授权模式

spring cloud集成oauth2实现微服务认证,调用oauth服务获取token,通过这个access_token去访问其它微服务,从而实现统一认证授权。oauth作为认证服务器之外也作为资源服务器,而其它每个服务器都自身也是一个资源服务器。

oauth2有四种授权模式

  1. 授权码模式(Authorization Code) 
  2. 授权码简化模式(Implicit)
  3. 密码模式(Resource Owner Password Credentials)
  4. Client模式(Client Credentials)

不管哪种授权模式都是从oauth服务器获取access_token,来访问其它资源服务器,以下用密码模式为例讲解

代码地址  https://gitee.com/zhangyu0914/oauth2.git

  1.  newretail-cloud-registry:注册服务
  2. newretail-cloud-config:配置中心
  3. newretail-cloud-gateway:网关
  4. newretail-cloud-auth:认证服务
  5. newretail-cloud-login:登录服务
  6. newretail-cloud-uc:用户中心
  7. newretail-cloud-upm:权限管理

一、配置中心

security:
  oauth2:
    resource:
      user-info-uri: http://gateway/api/auth/current
      id: ${spring.application.name:}
    client:
      client-id: webApp
      client-secret: 123456
      access-token-uri: http://gateway/api/auth/oauth/token
      grant-type: password
      scope: webApp

二、auth-service服务

     access_token存储在redis中,client_id、client_secret、grant_type、scope存在mysql数据库表里

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private DataSource dataSource;

    @Autowired
    private WebResponseExceptionTranslator webResponseExceptionTranslator;

    @Autowired
    private IntegrationAuthenticationFilter integrationAuthenticationFilter;

    @Autowired
    private IntegrationUserDetailsService integrationUserDetailsService;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(new JdbcClientDetailsService(dataSource));
    }

    @Bean
    public MyRedisTokenStore myRedisTokenStore() {
        return new MyRedisTokenStore(redisConnectionFactory);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                .tokenStore(myRedisTokenStore())
                .authenticationManager(authenticationManager)
                .exceptionTranslator(webResponseExceptionTranslator)
                .userDetailsService(integrationUserDetailsService)
                .reuseRefreshTokens(false);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients()
                .tokenKeyAccess("isAuthenticated()")
                .checkTokenAccess("permitAll()")
                .addTokenEndpointAuthenticationFilter(integrationAuthenticationFilter);
    }

}

密码模式需要加入AuthenticationManager

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic().and()
                .csrf().disable();

    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}

三、login-service服务

    login-service、uc-sercice、upm-service配置一样

# bootstrap.yml
spring:
  application:
    name: login-service
  cloud:
    config:
      #快速失败,避免雪崩
      fail-fast: true
      retry:
        max-attempts: 10
        max-interval: 10000
        initial-interval: 1000
      profile: ${SPRING_CLOUD_CONFIG_PROFILE:local}
      discovery:
        enabled: true
        service-id: config
      username: "admin"
      password: "123"
      #配置中心地址,环境变量读取不到则读取默认值
      #uri: ${SPRING_CLOUD_CONFIG_URI:http://admin:123@localhost:8888}

#ip地址
eureka:
  instance:
    instanceId: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

@UooguoNewretailApplication
public class LoginApplication extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        //TODO 需要加权限校验
        http.authorizeRequests()
                .antMatchers("/v2/api-docs", "/actuator/**", "/login").permitAll()
                .and().authorizeRequests().anyRequest().authenticated();
        //http.authorizeRequests().anyRequest().permitAll();
    }

    public static void main(String[] args) {
        SpringApplication.run(LoginApplication.class, args);
    }

}

以上是部分配置代码,详细请看码云上demo

四、postman调试

    1、登录调用auth服务获取access_token信息

    2、获取用户信息

五、springboot2集成oauth2遇到的坑

       1、访问此资源需要完全的身份验证

            调用feignClient时无法传递access_token出现认证失败,OAuth2ClientFeignConfiguration配置类实现RequestInterceptor              接口,重写apply方法将authorization加入header

      2、There is no PasswordEncoder mapped for the id "null"

             spring security 5.0之后加密格式改变了,SecurityConfig类中加入

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

 

未完待续!!!

  

展开阅读全文

没有更多推荐了,返回首页