从swagger-ui.html页面单击“授权”按钮时,出现“访问被拒绝”错误。
Exception :-
2019-02-13 15:03:18.209 DEBUG 7960 --- [nio-8080-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/oauth/token'; against '/hystrix/**'
2019-02-13 15:03:18.209 DEBUG 7960 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /oauth/token; Attributes: [#oauth2.throwOnError(authenticated)]
2019-02-13 15:03:18.209 DEBUG 7960 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@bbfccdd6: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2019-02-13 15:03:18.209 DEBUG 7960 --- [nio-8080-exec-4] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@1c8a3ec9, returned: -1
2019-02-13 15:03:18.211 DEBUG 7960 --- [nio-8080-exec-4] o.s.s.w.a.ExceptionTranslationFilter : **Access is denied (user is anonymous); redirecting to authentication entry point**
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-5.0.5.RELEASE.jar:5.0.5.RELEASE]
在8080端口上运行的资源服务器
SwaggerConfig.java
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport{
// password oauth
@Value("${app.client.id}")
private String clientId;
@Value("${app.client.secret}")
private String clientSecret;
@Value("${host.full.dns.auth.link}")
private String authLink;
@Bean
public Docket api() {
List<ResponseMessage> list = new ArrayList<>();
list.add(new ResponseMessageBuilder().code(500).message("500 message")
.responseModel(new ModelRef("Result")).build());
list.add(new ResponseMessageBuilder().code(401).message("Unauthorized")
.responseModel(new ModelRef("Result")).build());
list.add(new ResponseMessageBuilder().code(406).message("Not Acceptable")
.responseModel(new ModelRef("Result")).build());
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build()
.securitySchemes(Collections.singletonList(securitySchema()))
.securityContexts(Collections.singletonList(securityContext()))
;
}
private OAuth securitySchema() {
List<AuthorizationScope> authorizationScopeList = new ArrayList();
authorizationScopeList.add(new AuthorizationScope("read", "read all"));
authorizationScopeList.add(new AuthorizationScope("trust", "trust all"));
authorizationScopeList.add(new AuthorizationScope("write", "access all"));
List<GrantType> grantTypes = new ArrayList();
GrantType creGrant = new ResourceOwnerPasswordCredentialsGrant(authLink+"/oauth/token");
grantTypes.add(creGrant);
return new OAuth("oauth2schema", authorizationScopeList, grantTypes);
}
private SecurityContext securityContext() {
return SecurityContext.builder().securityReferences(defaultAuth()).forPaths(PathSelectors.ant("/**"))
.build();
}
private List<SecurityReference> defaultAuth() {
final AuthorizationScope[] authorizationScopes = new AuthorizationScope[3];
authorizationScopes[0] = new AuthorizationScope("read", "read all");
authorizationScopes[1] = new AuthorizationScope("trust", "trust all");
authorizationScopes[2] = new AuthorizationScope("write", "write all");
return Collections.singletonList(new SecurityReference("oauth2schema", authorizationScopes));
}
@Bean
public SecurityConfiguration securityInfo() {
return new SecurityConfiguration(clientId,clientSecret, "", "", "", ApiKeyVehicle.HEADER, "", " ");
}
/*private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("My API title").description("")
.termsOfServiceUrl("https://www.example.com/api")
.contact(new Contact("Hasson", "http://www.example.com", "hasson@example.com"))
.license("Open Source").licenseUrl("https://www.example.com").version("1.0.0").build();
}*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Application.properties
app.client.id = fooClientIdPassword
app.client.secret = secret
host.full.dns.auth.link = http://localhost:9090/auth
ResourceServerConfig.java
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId("my-resource");
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtTokenEnhancer());
}
@Bean
protected JwtAccessTokenConverter jwtTokenEnhancer() {
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(
new ClassPathResource("jwt.jks"),"mySecretKey".toCharArray());
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
return converter;
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.anonymous().and()
.authorizeRequests()
.antMatchers("/", "/lib/*", "/images/*", "/css/*", "/swagger-ui.js","/swagger-ui.min.js", "/api-docs", "/fonts/*", "/api-docs/*", "/api-docs/default/*", "/o2c.html","index.html","/webjars/**","/hystrix/**").permitAll()
.and().authorizeRequests().anyRequest().authenticated();
}
}
WebSecurityConfiguration.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userService")
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/**", "/csrf", "/v2/api-docs", "/swagger-resources/configuration/ui", "/configuration/ui", "/swagger-resources", "/swagger-resources/configuration/security", "/configuration/security", "/swagger-ui.html", "/webjars/**").permitAll()
.and().authorizeRequests().anyRequest().authenticated().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().csrf().disable()
;
}
@Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui/**", "/swagger-resources/**", "/configuration/security/**", "/swagger-ui.html", "/webjars/**");
}
}
在9090端口上运行的授权服务器
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private Environment environment;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore())
.tokenEnhancer(jwtTokenEnhancer())
.authenticationManager(authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
.passwordEncoder(passwordEncoder);
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtTokenEnhancer());
}
@Bean
protected JwtAccessTokenConverter jwtTokenEnhancer() {
String pwd = environment.getProperty("keystore.password");
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(
new ClassPathResource("jwt.jks"),
pwd.toCharArray());
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwt"));
return converter;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource).passwordEncoder(passwordEncoder);
}
}
从邮递员访问令牌详细信息:
**ClientId:fooClientIdPassword
Secret:secret
Username:admin@abc.abc
Password:admin
grantType: password
scope:read write**
使用此证书,对于邮递员来说效果很好。 我用swagger ui尝试过的证书也一样。它不起作用。