我正在尝试为我的角度应用程序启用oauth2令牌获取。我的配置运行正常(身份验证对于所有请求均正常运行,令牌提取也正常运行),但是有一个问题。
CORS请求要求在将GET OPTIONS请求发送到服务器之前。更糟糕的是,该请求不包含任何身份验证标头。我希望此请求始终返回200状态,而无需在服务器上进行任何身份验证。可能吗?也许我想念一些东西
我的Spring安全配置:
@Configuration @EnableWebSecurity @EnableAuthorizationServer public class SecurityConfig extends WebSecurityConfigurerAdapter { private static final Logger log = LoggerFactory.getLogger(SecurityConfig.class); @Inject private UserService userService; @Bean public TokenStore tokenStore() { return new InMemoryTokenStore(); } @Bean public DefaultTokenServices tokenServices() { DefaultTokenServices defaultTokenServices = new DefaultTokenServices(); defaultTokenServices.setTokenStore(tokenStore()); return defaultTokenServices; } @Bean public WebResponseExceptionTranslator webResponseExceptionTranslator() { return new DefaultWebResponseExceptionTranslator() { @Override public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception { ResponseEntity<OAuth2Exception> responseEntity = super.translate(e); OAuth2Exception body = responseEntity.getBody(); HttpHeaders headers = new HttpHeaders(); headers.setAll(responseEntity.getHeaders().toSingleValueMap()); headers.set("Access-Control-Allow-Origin", "*"); headers.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT"); headers.set("Access-Control-Max-Age", "3600"); headers.set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); return new ResponseEntity<>(body, headers, responseEntity.getStatusCode()); } }; } @Bean public AuthorizationServerConfigurer authorizationServerConfigurer() { return new AuthorizationServerConfigurer() { @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint = new OAuth2AuthenticationEntryPoint(); oAuth2AuthenticationEntryPoint.setExceptionTranslator(webResponseExceptionTranslator()); security.authenticationEntryPoint(oAuth2AuthenticationEntryPoint); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("secret-client") .secret("secret") .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") .authorities("ROLE_LOGIN") .scopes("read", "write", "trust") .accessTokenValiditySeconds(60 * 60 * 12); // 12 hours } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenServices(tokenServices()); endpoints.authenticationManager(authenticationManager()); } }; } @Override protected AuthenticationManager authenticationManager() throws Exception { return new AuthenticationManager() { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { log.warn("FIX ME: REMOVE AFTER DEBUG!!!!!!!!!!!!"); log.debug("authenticate: " + authentication.getPrincipal() + ":" + authentication.getCredentials()); final Collection<GrantedAuthority> authorities = new ArrayList<>(); WomarUser user = userService.findUser(authentication.getPrincipal().toString(), authentication.getCredentials().toString()); for (UserRole userRole : user.getRoles()) { authorities.add(new SimpleGrantedAuthority(userRole.getName())); } return new UsernamePasswordAuthenticationToken(user.getLogin(), user.getPassword(), authorities); } }; } @Bean public OAuth2AuthenticationManager auth2AuthenticationManager() { OAuth2AuthenticationManager oAuth2AuthenticationManager = new OAuth2AuthenticationManager(); oAuth2AuthenticationManager.setTokenServices(tokenServices()); return oAuth2AuthenticationManager; } @Bean public OAuth2AuthenticationProcessingFilter auth2AuthenticationProcessingFilter() throws Exception { OAuth2AuthenticationProcessingFilter oAuth2AuthenticationProcessingFilter = new OAuth2AuthenticationProcessingFilter(); oAuth2AuthenticationProcessingFilter.setAuthenticationManager(auth2AuthenticationManager()); return oAuth2AuthenticationProcessingFilter; } @Override protected void configure(HttpSecurity http) throws Exception { OAuth2AuthenticationEntryPoint oAuth2AuthenticationEntryPoint = new OAuth2AuthenticationEntryPoint(); oAuth2AuthenticationEntryPoint.setRealmName("realmName"); oAuth2AuthenticationEntryPoint.setTypeName("Basic"); oAuth2AuthenticationEntryPoint.setExceptionTranslator(webResponseExceptionTranslator()); http .antMatcher("/**").httpBasic() .authenticationEntryPoint(oAuth2AuthenticationEntryPoint) .and().addFilterBefore(auth2AuthenticationProcessingFilter(), BasicAuthenticationFilter.class) .authorizeRequests() .antMatchers("/rest/womar/admin/**").hasRole("ADMIN") .antMatchers("/rest/womar/**").hasRole("USER"); } }
angular request:
var config = { params: { grant_type: 'password', username: login, password: password }, headers: { Authorization: 'Basic ' + Base64.encode('secret-client' + ':' + 'secret') } }; $http.get("http://localhost:8080/oauth/token", config) .success(function(data, status) { $log.log('success'); $log.log(data); $log.log(status); }) .error(function(data, status) { $log.log('error'); $log.log(data); $log.log(status); });
@EnableAuthorizationServer是增加HTTP安全配置端点喜欢/oauth/token,/oauth/token_key在为了0等所以,你应该做的是定义一个http安全规则/oauth/token端点只为OPTIONS HTTP方法,它是在一个更高阶。
@EnableAuthorizationServer
/oauth/token
/oauth/token_key
像这样:
@Order(-1) @Configuration public class MyWebSecurity extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll() } }