故事
最近一直在加班,之前也没用国 Oauth2 进行权限控制,然后有点懵逼,导致配置了 Swagger 无法进行访问。无法访问包括:
1、页面无法访问
2、页面可以访问,访问接口报 401 没得权限
解决方法
解决页面访问问题
由于配置了 Oauth2,因此需要对 ResourceServerConfigurerAdapter 中的 configure 方法进行重写一下
具体内容如下:
import com.yth.oauth.component.YthUserAuthenticationConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
/**
* @author sirwsl
*/
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Resource
private RestTemplate restTemplate;
@Resource
private RemoteTokenServices remoteTokenServices;
@Override
public void configure(HttpSecurity http) throws Exception {
//排除认证
http.authorizeRequests().antMatchers(
"/webjars/**",
"/resources/**",
"/swagger-ui.html",
"/swagger-resources/**",
"/v2/api-docs",
"/login",
"/doc.html",
"/static",
"/",
"/oa/**").permitAll()
// 配置order访问控制,必须认证后才可以访问
.antMatchers("/**/**").authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
DefaultAccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter();
UserAuthenticationConverter userTokenConverter = new YthUserAuthenticationConverter();
accessTokenConverter.setUserTokenConverter(userTokenConverter);
remoteTokenServices.setRestTemplate(restTemplate);
remoteTokenServices.setAccessTokenConverter(accessTokenConverter);
resources.tokenServices(remoteTokenServices);
}
}
解决接口 401 问题
接口 401 因为没有授权,这个时候就需要考虑如何授权问题,因此我们对原有的 swagger 增加一些代码如下:
import com.google.common.base.Predicates;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* swagger配置类
* http://localhost:8080/swagger-ui.html
* @author sirwsl
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
private final String AUTH_SERVER = "exams";
@Bean
public Docket createApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.apis(Predicates.or(RequestHandlerSelectors.basePackage("com.yth.exam.api"),
RequestHandlerSelectors.basePackage("com.yth.course.api"),
RequestHandlerSelectors.basePackage("com.yth.score.api")))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo())
.securitySchemes(securitySchemes())
.securityContexts(securityContexts())
.groupName("所有API");
}
@Bean
public Docket createExamApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(examApi())
.select()
.paths(PathSelectors.any())
.paths(PathSelectors.ant("/xxx/**"))
.build()
.groupName("xxAPI")
.pathMapping("/");
}
@Bean
public Docket createDailyApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(dailyApi())
.select()
.paths(PathSelectors.ant("/xxx/**"))
.paths(PathSelectors.any())
.build()
.groupName("日常xxxAPI")
.pathMapping("/");
}
public ApiInfo apiInfo() {
return new ApiInfoBuilder().title("API")
.description("文档地址支持md语法")
.version("1.0.0").build();
}
private ApiInfo examApi() {
return new ApiInfoBuilder().title("xxxAPI").description("").version("1.0.0").build();
}
private ApiInfo dailyApi() {
return new ApiInfoBuilder().title("xxxAPI").description("").version("1.0.0").build();
}
/**
* 从这里开始是增加授权部分,具体的授权可以自己更改,这里采用token的方式
**/
private List<ApiKey> securitySchemes() {
List<ApiKey> apiKeys = new ArrayList<>();
apiKeys.add(new ApiKey("Authorization", "Authorization", "header"));
return apiKeys;
}
private List<SecurityContext> securityContexts() {
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$")).build());
return securityContexts;
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
}
实现效果如下
进入页面后会多了一个权限按钮,点击后可以添加 token,然后就可以访问
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于