具有多个grant_type的Spring Oauth2授权服务器用户信息端点不起作用
Posted
技术标签:
【中文标题】具有多个grant_type的Spring Oauth2授权服务器用户信息端点不起作用【英文标题】:Spring Oauth2 Authorization server User Info Endpoint with multiple grant_type not working 【发布时间】:2019-08-01 03:14:43 【问题描述】:我有一个具有内置数据库身份验证管理器的授权服务器。以下是配置。
AuthConfig.java
@Configuration
@EnableAuthorizationServer
public class AuthConfig extends AuthorizationServerConfigurerAdapter
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private DataSource dataSource;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception
clients.jdbc(dataSource).passwordEncoder(passwordEncoder).jdbc();
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
endpoints.authenticationManager(authenticationManager)
.tokenStore(tokenStore());
@Bean
public TokenStore tokenStore()
return new InMemoryTokenStore();
ResourceConfig.java
@Configuration
@EnableResourceServer
public class ResourceConfig extends ResourceServerConfigurerAdapter
@Override
public void configure(HttpSecurity http) throws Exception
http.authorizeRequests().antMatchers("/**").permitAll().and().authorizeRequests().antMatchers("/userinfo").authenticated();
SecurityConfig.java
@Configuration
@EnableWebSecurity
//@Order(SecurityProperties.IGNORED_ORDER) // If added grant_type password does not work
public class SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private DataSource dataSource;
@Override
public void configure(WebSecurity web) throws Exception
web.ignoring().antMatchers("/resources/**");
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
// @formatter:off
@Override
protected void configure(HttpSecurity http) throws Exception
http.authorizeRequests().antMatchers("/userinfo").authenticated().and().authorizeRequests()
.antMatchers("/login", "/oauth/token", "/oauth/**").permitAll().and().formLogin().and().csrf().disable()
.cors().disable();
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
.usersByUsernameQuery("select username,password,enabled from TBL_USERS where username = ?")
.authoritiesByUsernameQuery(
"select username, role as authority from TBL_USER_ROLES where username = ?");
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder(4);
用户信息.java
@RestController
public class UserInfo
@GetMapping(value="/userinfo")
public Map<String, Object> user(@AuthenticationPrincipal Principal principal)
if (principal != null)
return Map.of("name", principal.getName(), "authorities", SecurityContextHolder.getContext().getAuthentication().getAuthorities());
return null;
虽然上面的代码 sn-p 适用于 grant_type="password" 和其他能够检索用户信息以进行客户端验证的资源服务器。但是,当我使用grant_type="implicit"
授权服务器无法重定向到登录页面时出现身份验证错误,堆栈跟踪添加在下面。
2019-03-11 23:30:16.442 DEBUG 16401 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@a265b6db: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@380f4: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: 588FF6DC19A9313BFD6DA9E05BE589DC; Granted Authorities: ROLE_ANONYMOUS
2019-03-11 23:30:16.443 DEBUG 16401 --- [nio-8080-exec-4] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@7f86e65e, returned: 1
2019-03-11 23:30:16.443 DEBUG 16401 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2019-03-11 23:30:16.443 DEBUG 16401 --- [nio-8080-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2019-03-11 23:30:16.443 DEBUG 16401 --- [nio-8080-exec-4] o.s.security.web.FilterChainProxy : /oauth/authorize?response_type=token&state=&client_id=client_2&scope=&redirect_uri=http%3A%2F%2Flocalhost%3A8182%2Fresource2 reached end of additional filter chain; proceeding with original chain
2019-03-11 23:30:16.444 DEBUG 16401 --- [nio-8080-exec-4] .s.o.p.e.FrameworkEndpointHandlerMapping : Mapped to public org.springframework.web.servlet.ModelAndView org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(java.util.Map<java.lang.String, java.lang.Object>,java.util.Map<java.lang.String, java.lang.String>,org.springframework.web.bind.support.SessionStatus,java.security.Principal)
2019-03-11 23:30:16.449 DEBUG 16401 --- [nio-8080-exec-4] o.s.s.w.a.ExceptionTranslationFilter : Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.InsufficientAuthenticationException: User must be authenticated with Spring Security before authorization can be completed.
at org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint.authorize(AuthorizationEndpoint.java:143) ~[spring-security-oauth2-2.3.4.RELEASE.jar:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
我尝试过的一些替代方法是,删除 ResourceConfig 类,在这种情况下 Principal 对象保持为空(可能是因为没有注册提取令牌的过滤器),而我使用的另一种方法是在 SecurityConfig 中添加最高顺序,但在这种情况下隐式授权有效,密码授权无效
如何启用所有 grant_types 的 userInfo 端点?
【问题讨论】:
【参考方案1】:经过一番努力终于修复了,更多的是SecurityConfig.java
文件中的安全配置。
protected void configure(HttpSecurity http) throws Exception
http.requestMatchers().antMatchers("/login", "/oauth/authorize").and().authorizeRequests().anyRequest()
.authenticated().and().formLogin().permitAll().and().csrf().disable().cors().disable();
一个完整的例子是here
【讨论】:
我可以想象与这种链接的东西的斗争。疯了:(以上是关于具有多个grant_type的Spring Oauth2授权服务器用户信息端点不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Spring-Security-OAuth2 中的 grant_type
spring security client_credentials grant_type - 支持刷新令牌