SpringCloud Security, OAuth2, JWT 实现认证和授权(三)

新建一个模块,命名为stockservice,使用OAuth2进行服务保护,写两个API接口,一个需要验证,一个不需要验证。

1、添加maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>com.example.consul</groupId>
    <artifactId>common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

2、配置文件

server:
  port: 8803
spring:
  application:
    name: stockservice
  profiles:
    active: dev
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: stockservice
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/springcloud?useUnicode=true&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull
    password: root
    username: root

3、启动类

@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan(basePackages = {"com.example.consul.stockservice","com.example.consul.common"})
public class StockserviceApplication {

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

}

4、配置资源服务

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
    @Autowired
    private JWTConfig jwtConfig;
    
    /**
     * 权限认证失败的异常
     */
    @Bean
    public AccessDeniedHandler getAccessDeniedHandler() {
        return new ResourceAccessDeniedHandler();
    }

    /**
     * 未经授权异常
     * @return
     */
    @Bean
    public AuthenticationEntryPoint getAuthenticationEntryPoint() {
        return new ResourceAuthenticationEntryPoint();
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/stock/queryStock").permitAll()
                .antMatchers("/**").authenticated();
    }
    
    /**
     * 自定义token认证授权
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore())
                .accessDeniedHandler(getAccessDeniedHandler())
                .authenticationEntryPoint(getAuthenticationEntryPoint());
    }

    /**
     * 自定义验证token
     * 和认证服务器保持一致
     * @return
     */
    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtTokenEnhancer());
    }

    /**
     * jwt签名秘钥
     * @return
     */
    @Bean
    public JwtAccessTokenConverter jwtTokenEnhancer() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey(jwtConfig.getSigningKey());
        return jwtAccessTokenConverter;
    }

}
/**
 * 自定义未授权返回信息
 */
@Component
public class ResourceAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        HashMap<String, String> map = new HashMap<>();
        map.put("code", "500");
        map.put("msg", "未授权服务");
        map.put("uri", httpServletRequest.getRequestURI());
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
        ObjectMapper objectMapper = new ObjectMapper();
        String resBody = objectMapper.writeValueAsString(map);
        PrintWriter printWriter = httpServletResponse.getWriter();
        printWriter.print(resBody);
        printWriter.flush();
        printWriter.close();
    }
}
/**
 * 自定义权限不足信息
 */
@Component
public class ResourceAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        HashMap<String, String> map = new HashMap<>();
        map.put("code", "500");
        map.put("msg", "权限不足");
        map.put("uri", httpServletRequest.getRequestURI());
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
        ObjectMapper objectMapper = new ObjectMapper();
        String resBody = objectMapper.writeValueAsString(map);
        PrintWriter printWriter = httpServletResponse.getWriter();
        printWriter.print(resBody);
        printWriter.flush();
        printWriter.close();
    }
}

5、API接口

@RestController
@RequestMapping("stock")
public class StockController {

    @PostMapping("/info")
    @PreAuthorize("6")
    public String info() {
        return "info";
    }

    @GetMapping("/queryStock")
    public String queryStock() {
        return "queryStock";
    }
}

6、接口测试

postman模拟请求http://localhost:8803/stock/queryStock,不使用token,即不用验证,返回queryStock。

postman模拟请求http://localhost:8803/stock/info,不使用token,返回错误信息。

{
    "msg": "未进行授权,暂时无法访问",
    "code": "500",
    "uri": "/stock/info"
}

进行如下设置,通过验证后返回正确的结果:

猜你喜欢

转载自blog.csdn.net/suoyx/article/details/115289030