gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:03:43 25 4
gpt4 key购买 nike

我正在使用 Spring Security OAuth 构建一个 REST 应用程序。到目前为止,我可以发出请求以获取访问 token

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"}

但是当使用访问 token 请求安全资源时,由于 Spring 安全配置,我被重定向到登录页面。

@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

我尝试将 Spring 安全配置更改为:

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().hasRole("USER").and().httpBasic();
//super.configure(http);
}

但我没有重定向到 /login 页面,而是收到 HTTP/1.1 401 Unauthorized

但最糟糕的是,如果我在没有授权 header 和 access_token 的情况下添加用户凭据,我可以访问 protected 资源。

curl http://user:pass@localhost:8080/resources/demo && echo

WELCOME TO /demo!!

我在 spring 配置中有什么地方做错了吗?

这是整个项目:https://github.com/gee0292/OAuth2Demo

最佳答案

安全配置没有错误。

错误是我在 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;
}

因为所有的配置类都在同一个包中。

关于java - 如何配置 Spring Security 以使用 OAuth 而不是基本授权?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24917583/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com