spring cloud ouath2中的资源服务器

资源服务器就是业务服务 如用户服务,订单服务等 第三方需要到资源服务器调用接口获取资源

ResourceServerConfig

ResourceServerConfig是资源服务器的核心配置 用于验证token 与网关配置相似

其中.antMatchers("/**").access("#oauth2.hasScope('user')") 需要oauth_client_details表的scope配合 意思是访问所有资源 需要客户端有scope需要有user

@Configuration
@EnableResourceServer // 标识为资源服务器,请求服务中的资源,就要带着token过来,找不到token或token是无效访问不了资源
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法级别权限控制
public class ResourceServerConfig extends ResourceServerConfigurerAdapter implements CommandLineRunner {

    private final static Logger logger = LoggerFactory.getLogger(ResourceServerConfig.class);

    public static final String RESOURCE_ID = "user";

    /**
     * 权限不足返回给前端json
     */
    @Autowired
    private CustomAccessDeniedHandlerConfig customAccessDeniedHandlerConfig;

    @Autowired
    private TokenStore tokenStore;

    /**
     * token无效返回前段json
     */
    @Autowired
    private AuthExceptionEntryPointConfig authExceptionEntryPointConfig;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        // 当前资源服务器的资源id,认证服务会认证客户端有没有访问这个资源id的权限,有则可以访问当前服务
        resources.tokenStore(tokenStore).resourceId(RESOURCE_ID)
            // token无效异常的处理
            .authenticationEntryPoint(authExceptionEntryPointConfig)
            // 权限不足异常处理类
            .accessDeniedHandler(customAccessDeniedHandlerConfig)
             // 会话机制stateless开启
            .stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
            // SpringSecurity不会使用也不会创建HttpSession实例 因为整个oauth2后使用token
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
            // 开放swagger请求
            .antMatchers("/swagger-ui.html", "/webjars/**", "/swagger-resources/**","/v2/**").permitAll()
            // 所有请求,都需要有all范围(scope)
            .antMatchers("/**").access("#oauth2.hasScope('user')").
             anyRequest().authenticated().and().csrf()
            .disable();
    }

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

AuthExceptionEntryPointConfig,CustomAccessDeniedHandlerConfig

用于异常返回前端json

@Component
public class CustomAccessDeniedHandlerConfig implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
        AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.setStatus(HttpStatus.OK.value());
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        try {
            Result result = new Result(403, "权限不足");
            response.getWriter().write(new ObjectMapper().writeValueAsString(result));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
@Component
public class AuthExceptionEntryPointConfig implements AuthenticationEntryPoint{

    private final static Logger logger = LoggerFactory.getLogger(AuthExceptionEntryPointConfig.class);

    @Value("${security.redirect-url}")
    private String redirectUrl;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException authException) {
        Throwable cause = authException.getCause();
        response.setStatus(HttpStatus.OK.value());
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        Result result;
        try {
            if (cause instanceof InvalidTokenException) {
                result = new Result(402, "认证失败,无效或过期token");
                response.getWriter().write(new ObjectMapper().writeValueAsString(result));
            } else {
                result = new Result(401, "认证失败,没有携带token");
                response.sendRedirect(redirectUrl);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

TokenConfig

不多说

@Configuration
public class TokenConfig{

    /**
     * 使用redis存储
     */
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public TokenStore tokenStore() {
        return new RedisTokenStore(redisConnectionFactory);
    }

}

application.yml

那么小伙伴又问了 既然网关验证token的有效性 那么资源服务器是不是就不用验证啦 答案是否 因为不添加配置 会报错 同样需要在application中添加以下配置

其他配置也spirng boot为准 这里不多说

security:
  oauth2:
    client:
      client-id: user-vue
      client-secret: 1234
    resource:
      token-info-uri: http://localhost:8001/oauth/check_token

猜你喜欢

转载自blog.csdn.net/qq_20143059/article/details/113766105