本文就來說一下spring security oauth2的幾個endpoint的認證java
spring-security-oauth2-2.0.14.RELEASE-sources.jar!/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerEndpointsConfiguration.javaweb
@Configuration @Import(TokenKeyEndpointRegistrar.class) public class AuthorizationServerEndpointsConfiguration { private AuthorizationServerEndpointsConfigurer endpoints = new AuthorizationServerEndpointsConfigurer(); @Autowired private ClientDetailsService clientDetailsService; @Autowired private List<AuthorizationServerConfigurer> configurers = Collections.emptyList(); @PostConstruct public void init() { for (AuthorizationServerConfigurer configurer : configurers) { try { configurer.configure(endpoints); } catch (Exception e) { throw new IllegalStateException("Cannot configure enpdoints", e); } } endpoints.setClientDetailsService(clientDetailsService); } @Bean public AuthorizationEndpoint authorizationEndpoint() throws Exception { AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint(); FrameworkEndpointHandlerMapping mapping = getEndpointsConfigurer().getFrameworkEndpointHandlerMapping(); authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access")); authorizationEndpoint.setProviderExceptionHandler(exceptionTranslator()); authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error")); authorizationEndpoint.setTokenGranter(tokenGranter()); authorizationEndpoint.setClientDetailsService(clientDetailsService); authorizationEndpoint.setAuthorizationCodeServices(authorizationCodeServices()); authorizationEndpoint.setOAuth2RequestFactory(oauth2RequestFactory()); authorizationEndpoint.setOAuth2RequestValidator(oauth2RequestValidator()); authorizationEndpoint.setUserApprovalHandler(userApprovalHandler()); return authorizationEndpoint; } @Bean public TokenEndpoint tokenEndpoint() throws Exception { TokenEndpoint tokenEndpoint = new TokenEndpoint(); tokenEndpoint.setClientDetailsService(clientDetailsService); tokenEndpoint.setProviderExceptionHandler(exceptionTranslator()); tokenEndpoint.setTokenGranter(tokenGranter()); tokenEndpoint.setOAuth2RequestFactory(oauth2RequestFactory()); tokenEndpoint.setOAuth2RequestValidator(oauth2RequestValidator()); tokenEndpoint.setAllowedRequestMethods(allowedTokenEndpointRequestMethods()); return tokenEndpoint; } @Bean public CheckTokenEndpoint checkTokenEndpoint() { CheckTokenEndpoint endpoint = new CheckTokenEndpoint(getEndpointsConfigurer().getResourceServerTokenServices()); endpoint.setAccessTokenConverter(getEndpointsConfigurer().getAccessTokenConverter()); endpoint.setExceptionTranslator(exceptionTranslator()); return endpoint; } @Bean public WhitelabelApprovalEndpoint whitelabelApprovalEndpoint() { return new WhitelabelApprovalEndpoint(); } @Bean public WhitelabelErrorEndpoint whitelabelErrorEndpoint() { return new WhitelabelErrorEndpoint(); } //...... }
這裏顯示配置了以下幾個spring
這個須要保護用戶帳號密碼認證保護,不然會報express
curl -i http://localhost:8080/oauth/authorize\?response_type\=code\&client_id\=demoApp\&redirect_uri\=http://localhost:8081/callback HTTP/1.1 500 X-Application-Context: application Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Sun, 10 Dec 2017 07:12:50 GMT Connection: close {"timestamp":1512889970484,"status":500,"error":"Internal Server Error","exception":"org.springframework.security.authentication.InsufficientAuthenticationException","message":"User must be authenticated with Spring Security before authorization can be completed.","path":"/oauth/authorize"}
這個走basic認證保護json
這個須要認證保護,不然報500session
curl -i http://localhost:8080/oauth/confirm_access HTTP/1.1 500 X-Application-Context: application Cache-Control: no-store Content-Type: application/json;charset=UTF-8 Content-Language: zh-CN Transfer-Encoding: chunked Date: Sun, 10 Dec 2017 07:13:55 GMT Connection: close {"timestamp":1512890035907,"status":500,"error":"Internal Server Error","exception":"org.springframework.expression.spel.SpelEvaluationException","message":"EL1008E: Property or field 'authorizationRequest' cannot be found on object of type 'java.util.HashMap' - maybe not public?","path":"/oauth/confirm_access"}
這個能夠不用認證保護app
spring-security-oauth2-2.0.14.RELEASE-sources.jar!/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.javacurl
@Override protected void configure(HttpSecurity http) throws Exception { AuthorizationServerSecurityConfigurer configurer = new AuthorizationServerSecurityConfigurer(); FrameworkEndpointHandlerMapping handlerMapping = endpoints.oauth2EndpointHandlerMapping(); http.setSharedObject(FrameworkEndpointHandlerMapping.class, handlerMapping); configure(configurer); http.apply(configurer); String tokenEndpointPath = handlerMapping.getServletPath("/oauth/token"); String tokenKeyPath = handlerMapping.getServletPath("/oauth/token_key"); String checkTokenPath = handlerMapping.getServletPath("/oauth/check_token"); if (!endpoints.getEndpointsConfigurer().isUserDetailsServiceOverride()) { UserDetailsService userDetailsService = http.getSharedObject(UserDetailsService.class); endpoints.getEndpointsConfigurer().userDetailsService(userDetailsService); } // @formatter:off http .authorizeRequests() .antMatchers(tokenEndpointPath).fullyAuthenticated() .antMatchers(tokenKeyPath).access(configurer.getTokenKeyAccess()) .antMatchers(checkTokenPath).access(configurer.getCheckTokenAccess()) .and() .requestMatchers() .antMatchers(tokenEndpointPath, tokenKeyPath, checkTokenPath) .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER); // @formatter:on http.setSharedObject(ClientDetailsService.class, clientDetailsService); }
其中,能夠本身指定check_token的認證級別,而/oauth/token則須要fullyAuthenticatedide
token_key這個是jwt特有的,這裏忽略不講lua
一個是authenticated,一個是fullyAuthenticated,前者排除anonymous,後者排除anonymous以及remember-me
Returns true if the user is not anonymous
Returns true if the user is not an anonymous or a remember-me user
綜上,須要保護/oauth/authorize以及/oauth/confirm_access這兩個endpoint,固然主要是/oauth/authorize這個。
因爲其餘幾個/oauth/開頭的認證endpoint配置的認證優先級高於默認的WebSecurityConfigurerAdapter配置(order=100),所以默認的能夠這樣配置
@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http .requestMatchers().antMatchers("/oauth/**","/login/**","/logout/**") .and() .authorizeRequests() .antMatchers("/oauth/**").authenticated() .and() .formLogin().permitAll(); //新增login form支持用戶登陸及受權 } }
把整個/oauth/**保護進來