oauth2 身份验证成功并获得匿名令牌后收到 404

Mah*_*leh 5 spring-security oauth-2.0 spring-boot spring-security-oauth2 spring-oauth2

我将 oauth2 与springboot 1.5.6.RELEASE一起使用,并且将 jdbc 身份验证与 oauth2 一起使用。

\n\n

我添加了属性:security.oauth2.resource.filter-order = 3

\n\n

1-授权服务器配置适配器:

\n\n
@Configuration\n@EnableAuthorizationServer\npublic class OAuth2Config extends AuthorizationServerConfigurerAdapter {\n\n    @Autowired\n    @Qualifier("authenticationManagerBean")\n    @Lazy\n    private AuthenticationManager authenticationManager;\n\n    @Autowired\n    private Environment env;\n\n    @Override\n    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {\n\n        // endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager);\n        endpoints.authenticationManager(authenticationManager);\n    }\n\n    @Bean\n    public TokenStore tokenStore() {\n        return new JdbcTokenStore(dataSource());\n    }\n\n    @Override\n    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {\n        security.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");\n    }\n\n    @Override\n    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {\n        clients.jdbc(dataSource());\n    }\n\n    @Bean\n    public DataSource dataSource() {\n        DriverManagerDataSource dataSource = new DriverManagerDataSource();\n        dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));\n        dataSource.setUrl(env.getProperty("spring.datasource.url"));\n        dataSource.setUsername(env.getProperty("spring.datasource.username"));\n        dataSource.setPassword(env.getProperty("spring.datasource.password"));\n        return dataSource;\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

2-资源服务器配置适配器

\n\n
@EnableResourceServer\npublic class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {\n\n    @Override\n    public void configure(HttpSecurity http) throws Exception {\n        http.antMatcher("/ws/**").authorizeRequests().anyRequest().authenticated();\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

3-安全配置

\n\n
@Configuration\n@EnableWebSecurity\nclass SecurityConfig extends WebSecurityConfigurerAdapter {\n\n    @Autowired\n    private UserDetailsService userDetailsService;\n\n    @Autowired\n    private CustomAuthenticationSuccessHandler successHandler;\n\n    @Override\n    protected void configure(HttpSecurity http) throws Exception {\n        http.csrf().disable();\n        http.authorizeRequests()\n                .antMatchers("/", "/registerCompany", "/registerEmployee", "/jobs", "/returnPassword", "/resetPassword",\n                        "/faces/public/**", "/resources/**", "/template/**", "/faces/fonts/*",\n                        "/faces/javax.faces.resource/**", "/ws/**", "/login", "/oauth/**", "/error")\n                .permitAll().antMatchers("/admin/**", "/faces/admin/**").hasAuthority("ROLE_ADMIN")\n                .antMatchers("/employeeProfile", "/employeeMainPage", "/employeeAskJob").hasAuthority("ROLE_EMPLOYEE")\n                .antMatchers("/companyProfile", "/companyMainPage", "/companyPostJob", "/companySearch",\n                        "/branchProfile")\n                .hasAnyAuthority("ROLE_COMPANY,ROLE_BRANCH,ROLE_ADMIN").anyRequest().fullyAuthenticated().and()\n                .formLogin().loginPage("/login").permitAll().successHandler(successHandler).failureUrl("/login?error")\n                .usernameParameter("username").passwordParameter("password").and().logout().deleteCookies("JSESSIONID")\n                .logoutUrl("/logout").deleteCookies("remember-me").logoutSuccessUrl("/").permitAll().and().rememberMe();\n        // http.sessionManagement().invalidSessionUrl("/login?invalidSession");\n\n        // cache resources\n        http.headers().addHeaderWriter(new DelegatingRequestMatcherHeaderWriter(\n                new AntPathRequestMatcher("/javax.faces.resource/**"), new HeaderWriter() {\n\n                    @Override\n                    public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {\n                        response.addHeader("Cache-Control", "private, max-age=86400");\n                    }\n                })).defaultsDisabled();\n    }\n\n    @Override\n    @Bean\n    public AuthenticationManager authenticationManagerBean() throws Exception {\n        return super.authenticationManagerBean();\n    }\n\n    @Override\n    public void configure(AuthenticationManagerBuilder auth) throws Exception {\n        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());\n    }\n\n    @Bean\n    public PasswordEncoder passwordEncoder() {\n        return new BCryptPasswordEncoder(11);\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我正在尝试使用邮递员生成一个令牌,并向 url http://localhost:8082/dawam2/oauth/token?grant_type=password\n 发送请求,并且我使用基本身份验证并设置username=myclient_idpassword=myclient_secret。因此生成了标头(授权:Basic Basic bXljbGllbnRfaWQ6bXljbGllbnRfc2VjcmV0) \n并且我设置了标头Content-Type: application/x-www-form-urlencoded; 字符集=utf-8

\n\n

我得到的响应而不是生成的令牌:

\n\n
!doctype html><html lang="en"><head><title>HTTP Status 404 \xe2\x80\x93 Not Found</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 \xe2\x80\x93 Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> Not Found</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.0.M18</h3></body></html>\n
Run Code Online (Sandbox Code Playgroud)\n\n

以下是调试信息:

\n\n
     2017-09-26 15:32:16,833 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/oauth/token\']\n2017-09-26 15:32:16,833 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : \'/oauth/token\'; against \'/oauth/token\'\n2017-09-26 15:32:16,833 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - matched\n2017-09-26 15:32:16,833 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 1 of 11 in additional filter chain; firing Filter: \'WebAsyncManagerIntegrationFilter\'\n2017-09-26 15:32:16,833 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 2 of 11 in additional filter chain; firing Filter: \'SecurityContextPersistenceFilter\'\n2017-09-26 15:32:16,833 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 3 of 11 in additional filter chain; firing Filter: \'HeaderWriterFilter\'\n2017-09-26 15:32:16,833 DEBUG o.s.s.w.h.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@1d47c7a\n2017-09-26 15:32:16,833 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 4 of 11 in additional filter chain; firing Filter: \'LogoutFilter\'\n2017-09-26 15:32:16,833 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/logout\', GET]\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : \'/oauth/token\'; against \'/logout\'\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/logout\', POST]\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request \'GET /oauth/token\' doesn\'t match \'POST /logout\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/logout\', PUT]\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request \'GET /oauth/token\' doesn\'t match \'PUT /logout\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/logout\', DELETE]\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request \'GET /oauth/token\' doesn\'t match \'DELETE /logout\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - No matches found\n2017-09-26 15:32:16,834 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 5 of 11 in additional filter chain; firing Filter: \'BasicAuthenticationFilter\'\n2017-09-26 15:32:16,834 DEBUG o.s.s.w.a.w.BasicAuthenticationFilter - Basic Authentication Authorization header found for user \'myclient_id\'\n2017-09-26 15:32:16,834 DEBUG o.s.s.a.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider\n2017-09-26 15:32:16,849 DEBUG o.s.s.w.a.w.BasicAuthenticationFilter - Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d9cf8114: Principal: org.springframework.security.core.userdetails.User@6a9879e3: Username: myclient_id; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_EMPLOYEE; 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_EMPLOYEE\n2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 6 of 11 in additional filter chain; firing Filter: \'RequestCacheAwareFilter\'\n2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 7 of 11 in additional filter chain; firing Filter: \'SecurityContextHolderAwareRequestFilter\'\n2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 8 of 11 in additional filter chain; firing Filter: \'AnonymousAuthenticationFilter\'\n2017-09-26 15:32:16,850 DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - SecurityContextHolder not populated with anonymous token, as it already contained: \'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d9cf8114: Principal: org.springframework.security.core.userdetails.User@6a9879e3: Username: myclient_id; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_EMPLOYEE; 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_EMPLOYEE\'\n2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 9 of 11 in additional filter chain; firing Filter: \'SessionManagementFilter\'\n2017-09-26 15:32:16,850 DEBUG o.s.s.w.a.s.CompositeSessionAuthenticationStrategy - Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@15d6aaa\n2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 10 of 11 in additional filter chain; firing Filter: \'ExceptionTranslationFilter\'\n2017-09-26 15:32:16,850 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password at position 11 of 11 in additional filter chain; firing Filter: \'FilterSecurityInterceptor\'\n2017-09-26 15:32:16,850 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : \'/oauth/token\'; against \'/oauth/token\'\n2017-09-26 15:32:16,850 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token?grant_type=password; Attributes: [fullyAuthenticated]\n2017-09-26 15:32:16,850 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@d9cf8114: Principal: org.springframework.security.core.userdetails.User@6a9879e3: Username: myclient_id; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_EMPLOYEE; 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_EMPLOYEE\n2017-09-26 15:32:16,851 DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@14cb584, returned: 1\n2017-09-26 15:32:16,851 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - Authorization successful\n2017-09-26 15:32:16,851 DEBUG o.s.s.w.a.i.FilterSecurityInterceptor - RunAsManager did not change Authentication object\n2017-09-26 15:32:16,851 DEBUG o.s.security.web.FilterChainProxy - /oauth/token?grant_type=password reached end of additional filter chain; proceeding with original chain\n2017-09-26 15:32:16,853 DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally\n2017-09-26 15:32:16,853 DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/oauth/token\']\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : \'/error\'; against \'/oauth/token\'\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/oauth/token_key\']\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : \'/error\'; against \'/oauth/token_key\'\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/oauth/check_token\']\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : \'/error\'; against \'/oauth/check_token\'\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - No matches found\n2017-09-26 15:32:16,854 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 1 of 12 in additional filter chain; firing Filter: \'WebAsyncManagerIntegrationFilter\'\n2017-09-26 15:32:16,854 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 2 of 12 in additional filter chain; firing Filter: \'SecurityContextPersistenceFilter\'\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No HttpSession currently exists\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: null. A new one will be created.\n2017-09-26 15:32:16,854 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 3 of 12 in additional filter chain; firing Filter: \'HeaderWriterFilter\'\n2017-09-26 15:32:16,854 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 4 of 12 in additional filter chain; firing Filter: \'LogoutFilter\'\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/logout\', GET]\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Checking match of request : \'/error\'; against \'/logout\'\n2017-09-26 15:32:16,854 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/logout\', POST]\n2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request \'GET /error\' doesn\'t match \'POST /logout\n2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/logout\', PUT]\n2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request \'GET /error\' doesn\'t match \'PUT /logout\n2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - Trying to match using Ant [pattern=\'/logout\', DELETE]\n2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request \'GET /error\' doesn\'t match \'DELETE /logout\n2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.matcher.OrRequestMatcher - No matches found\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 5 of 12 in additional filter chain; firing Filter: \'UsernamePasswordAuthenticationFilter\'\n2017-09-26 15:32:16,855 DEBUG o.s.s.w.u.m.AntPathRequestMatcher - Request \'GET /error\' doesn\'t match \'POST /login\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 6 of 12 in additional filter chain; firing Filter: \'RequestCacheAwareFilter\'\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 7 of 12 in additional filter chain; firing Filter: \'SecurityContextHolderAwareRequestFilter\'\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 8 of 12 in additional filter chain; firing Filter: \'RememberMeAuthenticationFilter\'\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 9 of 12 in additional filter chain; firing Filter: \'AnonymousAuthenticationFilter\'\n2017-09-26 15:32:16,855 DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Populated SecurityContextHolder with anonymous token: \'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: 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\'\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 10 of 12 in additional filter chain; firing Filter: \'SessionManagementFilter\'\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 11 of 12 in additional filter chain; firing Filter: \'ExceptionTranslationFilter\'\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password at position 12 of 12 in additional filter chain; firing Filter: \'FilterSecurityInterceptor\'\n2017-09-26 15:32:16,855 DEBUG o.s.security.web.FilterChainProxy - /error?grant_type=password reached end of additional filter chain; proceeding with original chain\n2017-09-26 15:32:16,856 DEBUG o.s.s.w.c.HttpSessionSecurityContextRepository - SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.\n2017-09-26 15:32:16,856 DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally\n2017-09-26 15:32:16,856 DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed\n
Run Code Online (Sandbox Code Playgroud)\n\n

我该如何解决这个问题?

\n

Mah*_*leh 1

该问题与Jersey 配置有关,它正在窃取来自 oauth2 的请求,我必须重新配置它,@ApplicationPath("/ws") 因此配置现在如下所示:

@Configuration
@ApplicationPath("/ws")
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(DawamService.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的网络服务实现类如下:

@Component
@Path("/dawam")
public class DawamService extends DawamServiceBase {

       @GET
       @Produces({ MediaType.TEXT_HTML })
       @Path("/test")
       public String getHTML() {
         System.out.println("##### Welcome to test webservice #########");
         return "Welcome to test webservice";
       }
}
Run Code Online (Sandbox Code Playgroud)