当我尝试从招摇中访问OAuth2时得到401。如果将Swagger配置在同一项目中并在同一端口上运行,则工作正常。但是,当我在另一个具有不同端口的项目中配置swagger时,它将显示401。
OAuth2可以访问,并且可以与Postman一起正常工作。我无法找到为什么从其他端口发出401。我检查了运行端口的入站/出站规则。从其他服务器或端口访问OAuth是否需要其他配置?
OAuth2项目已在http://localhost:8090/上配置 在http://localhost:8888/上配置了SpringBoot项目,OAuth2从该位置开始提供401。
WebSecurityConfiguration
@Configuration
@EnableWebSecurity
public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Lazy
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/oauth/**").permitAll()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().disable();
}
/*
* https://github.com/spring-projects/spring-boot/issues/11136
* Expose it manually (there is bug)
*
* */
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
AuthorizationServerConfig:
@Configuration
@EnableAuthorizationServer
public class CustomAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private static final String CLIENT_ID = "client";
private static final String CLIENT_SECRET = "secret";
private static final String GRANT_TYPE_PASSWORD = "password";
private static final String GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials";
private static final String GRANT_TYPE_REFRESH_TOKEN = "refresh_token";
private static final String GRANT_TYPE_AUTH_CODE = "authorization_code";
private static final String SCOPE_READ = "read";
private static final String SCOPE_WRITE = "write";
private static final String SCOPE_TRUST = "trust";
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private CustomUserDetailService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Value("${config.oauth2.tokenTimeout}")
private int ACCESS_TOKEN_VALIDITY_SECONDS;
@Value("${config.oauth2.tokenTimeout}")
private int REFRESH_TOKEN_VALIDITY_SECONDS;
@Value("${config.oauth2.privateKey}")
private String privateKey;
@Value("${config.oauth2.publicKey}")
private String publicKey;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient(CLIENT_ID)
.authorizedGrantTypes(GRANT_TYPE_CLIENT_CREDENTIALS, GRANT_TYPE_PASSWORD, GRANT_TYPE_REFRESH_TOKEN, GRANT_TYPE_AUTH_CODE)
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes(SCOPE_READ, SCOPE_WRITE, SCOPE_TRUST)
.resourceIds("oauth2-resource")
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS)
.refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS)
.secret(passwordEncoder.encode(CLIENT_SECRET));
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
.tokenStore(tokenStore())
.userDetailsService(userDetailsService)
.tokenServices(tokenServices())
.accessTokenConverter(accessTokenConverter());
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(privateKey);
return converter;
}
@Bean
public JwtTokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setTokenEnhancer(accessTokenConverter());
return defaultTokenServices;
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.checkTokenAccess("isAuthenticated()")
.tokenKeyAccess("permitAll()");
}
}
WebSecureConfigurerAdapter:
@Configuration
@EnableResourceServer
public class CustomResourceConfig extends ResourceServerConfigurerAdapter {
@Value("${config.oauth2.publicKey}")
private String publicKey;
@Value("${config.oauth2.privateKey}")
private String privateKey;
@Value("${config.oauth2.resource.id}")
private String resourceId;
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).authenticated()
.antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers("/", "/home", "/register", "/login").permitAll()
.antMatchers("/oauth/**").authenticated();
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources
.resourceId(resourceId)
.tokenServices(tokenServices())
.tokenStore(tokenStore());
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setTokenEnhancer(accessTokenConverter());
return defaultTokenServices;
}
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(privateKey);
return converter;
}
@Bean
public JwtTokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
}
答案 0 :(得分:0)
在Swagger配置中,创建Docket实例时应正确初始化OAuth安全模式。这里的访问令牌URI类似于:http://localhost:8080/api/oauth/token
@Value("${config.oauth2.accessTokenUri}")
private String accessTokenUri;
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select().apis(RequestHandlerSelectors.basePackage("com.authentication")).paths(regex("/.*"))
.paths(PathSelectors.any())
.build()
.securityContexts(Collections.singletonList(securityContext()))
.securitySchemes(Arrays.asList(securitySchema()))
.apiInfo(apiInfo());
}
private OAuth securitySchema() {
List<AuthorizationScope> authorizationScopeList = newArrayList();
authorizationScopeList.add(new AuthorizationScope("read", "read all"));
authorizationScopeList.add(new AuthorizationScope("write", "access all"));
List<GrantType> grantTypes = newArrayList();
GrantType passwordCredentialsGrant = new ResourceOwnerPasswordCredentialsGrant(accessTokenUri);
grantTypes.add(passwordCredentialsGrant);
return new OAuth("oauth2", authorizationScopeList, grantTypes);
}
private SecurityContext securityContext() {
return SecurityContext.builder().securityReferences(defaultAuth())
.build();
}