当前位置: 首页 > 知识库问答 >
问题:

如何配置Spring Security以使用OAuth而不是基本授权?

燕朝明
2023-03-14
curl http://localhost:8080/oauth/token -d "username=user&password=pass&client_id=client&client_secret=secret&grant_type=password"

并得到成功的回应

{"access_token":"b9590e0c-dc2c-4578-9246-ab46ab626b2c","token_type":"bearer","refresh_token":"56b73a2c-9993-4bbe-90db-58d207aeb3f1","expires_in":3599,"scope":"read"}

但是当使用访问令牌请求安全资源时,我会被重定向到Spring Security配置的登录页面bacause。

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("pass").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
    }
}

Spring Security OAuth2配置

@Configuration
public class OAuth2ServerConfig {

    protected static final String RESOURCE_ID = "oauthdemo";

    @Configuration
    @EnableResourceServer
    protected static class ResourceServer extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                    .requestMatchers().antMatchers("/resources/**").and()
                    .authorizeRequests()
                    .anyRequest().access("#oauth2.hasScope('read')");
        }

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            resources.resourceId(RESOURCE_ID);
        }
    }


    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

        @Autowired
        @Qualifier("authenticationManagerBean")
        private AuthenticationManager authenticationManager;

        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            oauthServer.allowFormAuthenticationForClients();
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.authenticationManager(authenticationManager);
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                    .withClient("client")
                    .authorizedGrantTypes("password", "refresh_token")
                    .authorities("ROLE_USER")
                    .scopes("read")
                    .resourceIds(RESOURCE_ID)
                    .secret("secret").accessTokenValiditySeconds(3600);
        }

    }
}
curl -H "Authorization: Bearer b9590e0c-dc2c-4578-9246-ab46ab626b2c" -v http://localhost:8080/resources/demo

* Adding handle: conn: 0x7fec92003000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7fec92003000) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 8080 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /resources/demo HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8080
> Accept: */*
> Authorization: Bearer b9590e0c-dc2c-4578-9246-ab46ab626b2c
> 
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=AD13E5504E72BDFED23E4C253A584D68; Path=/; HttpOnly
< Location: http://localhost:8080/login
< Content-Length: 0
< Date: Wed, 23 Jul 2014 17:23:12 GMT
< 
* Connection #0 to host localhost left intact
@Override
 protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().hasRole("USER").and().httpBasic();
    //super.configure(http);
}
curl http://user:pass@localhost:8080/resources/demo && echo

WELCOME TO /demo!!

以下是整个程序:https://github.com/gee0292/oauth2demo

共有1个答案

庄阿苏
2023-03-14

安全配置中没有错误。

错误是我只在CreateRootContext中注册了自动化服务器。

public class WebAppInitializer implements WebApplicationInitializer {

    ...

    private WebApplicationContext createRootContext(ServletContext servletContext) {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

        rootContext.register(CoreConfig.class, SecurityConfig.class, OAuth2ServerConfig.OAuth2Config.class, MethodSecurityConfig.class);
        rootContext.refresh();

        servletContext.addListener(new ContextLoaderListener(rootContext));
        servletContext.setInitParameter("defaultHtmlEscape", "true");

        return rootContext;
    }

    ...
}

rootcontext.register(...)中,我注册的是oauth2ServerConfig.oauth2Config.class,而不是oauth2ServerConfig.class,这导致只有授权服务器工作。

private WebApplicationContext createRootContext(ServletContext servletContext) {
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    //rootContext.register(CoreConfig.class, SecurityConfig.class, OAuth2ServerConfig.class, MethodSecurityConfig.class);
    //rootContext.refresh();

    rootContext.scan(ClassUtils.getPackageName(this.getClass()));

    servletContext.addListener(new ContextLoaderListener(rootContext));
    servletContext.setInitParameter("defaultHtmlEscape", "true");

    return rootContext;
}
 类似资料:
  • 我试图使用Gson发送JsonObjects作为响应。这些JsonObjects是手工构造的,而不是使用objectMapper或GSON。我排除了所有与杰克逊有关的依赖关系。它工作得很好很好。后来,我尝试使用SpringFox添加Swagger文档。现在它抛出以下异常:

  • 我有一个Spring项目,它使用sping-oaust2和sping-Security使用LDAP身份验证提供程序进行身份验证。 在控制器中,我可以使用< code > @ AuthenticationPrincipal 注释访问当前主体的< code>UserDetails。 然而,当我使用client_credential令牌到达endpoint时,是一个,它是OAuth客户端id。sprin

  • 但是,我需要它从我们的nexus服务中提取:。在docker-compose文件中,我已经使用了正确的nexus图像路径。(通过用docker-compose手动启动它来验证。然而,TestContainers也会拉入docker-compose文件之外的其他图像。正是这些图像导致了失败。 我很高兴Docker Desktop或TestContainers的配置更改能解决这个问题。 注意:我已经尝

  • 我试图在一个已经设置了基本auth的Spring Boot应用程序中配置CORS。 我在很多地方搜索过,包括这个答案,它指向官方文档中基于过滤器的CORS支持。 到目前为止还没有运气。

  • 我正在使用Google API Client Library for JavaScript(Beta)在Web应用程序上授权用户google帐户(用于youtube操作)。一切正常,但我不知道如何从我的应用程序中“注销”用户,即重置访问令牌。 例如,以下代码检查用户授权,如果没有,则显示弹出窗口,供用户登录帐户并允许web应用程序访问用户数据: 但是客户端库没有重置授权的方法。 有一个变通方法,将

  • 我正在用Spring(无Spring Boot)构建一个Java客户端,并且必须使用Gson。 我如何告诉Spring使用Gson而不是Jackson? 为了澄清,我使用了反应式WebClient: Pojo应该是这样的: 服务器中的Json是这样的: