[英]Java Spring Security: 401 Unauthorized for token OAuth2 end point
I have a fairly basic setup in my Spring Boot project.我的 Spring Boot 项目中有一个相当基本的设置。 I'm trying to set up OAuth2 to protect my API but I'm running into issues with my
/oauth/token
end point.我正在尝试设置 OAuth2 来保护我的 API,但我
/oauth/token
了/oauth/token
端点的问题。 Making either a POST or GET request to my /oauth/token
end point results in the following response (With a 401 Unauthorized
status code):向我的
/oauth/token
端点发出 POST 或 GET 请求会导致以下响应(带有401 Unauthorized
状态代码):
{
"timestamp": "2018-09-17T16:46:59.961+0000",
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/oauth/token"
}
This is my Authorization server configuration.这是我的授权服务器配置。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client_id")
.secret("secret")
.authorizedGrantTypes("password", "authorization_code", "refresh_token")
.scopes("read", "write")
.accessTokenValiditySeconds(600)
.refreshTokenValiditySeconds(3600);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(this.tokenStore)
.userApprovalHandler(this.userApprovalHandler)
.authenticationManager(this.authenticationManager);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
.passwordEncoder(this.passwordEncoder);
}
}
This is my resource server configuration.这是我的资源服务器配置。 Nothing significant yet:
还没有什么重要的:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired
private TokenStore tokenStore;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(this.tokenStore);
}
}
And finally my standard web security configuration:最后是我的标准网络安全配置:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
public void globalUserDetails(AuthenticationManagerBuilder builder) throws Exception {
builder.inMemoryAuthentication()
.withUser("user").password("password").roles("ADMIN")
.and()
.withUser("admin").password("password").roles("USER");
}
@Override
protected void configure(HttpSecurity security) throws Exception {
security.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(8);
}
@Bean
@Autowired
public UserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(this.clientDetailsService));
handler.setClientDetailsService(this.clientDetailsService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
}
I've messed around quite a bit with different matcher patterns to see if I can get it working but I haven't had any luck.我已经用不同的匹配器模式搞砸了很多,看看我是否可以让它工作,但我没有任何运气。 I'm running this in a root context and servlet path on
http://localhost:8080
.我在
http://localhost:8080
上的根上下文和 servlet 路径中运行它。
I can confirm that the end point is mapped in the output when Spring Boot fires up and trying to hit a slightly different end point results in an expected 404.我可以确认,当 Spring Boot 启动并尝试到达稍微不同的端点时,端点已映射到输出中,结果是预期的 404。
Turns out I wasn't hitting the end point correctly.原来我没有正确到达终点。 I was sending all of my data, client credentials included, via HTTP POST.
我正在通过 HTTP POST 发送我的所有数据,包括客户端凭据。
POST http://localhost:8080/oauth/token
...
client_id=client_id&secret=secret&scope=read&grant_type=password&username=user&password=password
I needed to use HTTP Basic Auth to send my client credentials rather than POSTing them:我需要使用 HTTP 基本身份验证来发送我的客户端凭据而不是发布它们:
POST http://localhost:8080/oauth/token
Authorization: Basic Y2xpZW50X2lkOnNlY3JldA==
...
scope=read&grant_type=password&username=user&password=password
try changing your password encoder from your AuthorizationServerConfig
class with this simple encoder(it doesn't encrypt passwords).because you don't save your client secret in InMemory storage with encryption.尝试使用这个简单的编码器从
AuthorizationServerConfig
类更改密码编码器(它不加密密码)。因为您没有将客户端密码保存在 InMemory 存储中并加密。
private PasswordEncoder getPasswordEncoder() {
return new PasswordEncoder() {
public String encode (CharSequence charSequence) {
return charSequence.toString();
}
public boolean matches(CharSequence charSequence, String s) {
return true;
}
};
}
hope it will work.希望它会起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.