spring security oauth2 java config – 处理程序调度失败;嵌套异常是java.lang.StackOverflowError

weixin_38060120 2019-09-12 12:46:39
在java配置中使用OAuth2配置Spring Security,而client_credentails流工作正常,但是密码流正在抛出Handler dispatch失败;嵌套异常是java.lang.StackOverflowError,下面是日志信息 2016-10-10 23:19:08 DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver – 解析处理程序中的异常[public org.springframework.http.ResponseEntity< org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map< java.lang.String,java.lang.String>)throws org.springframework.web.HttpRequestMethodNotSupportedException] :org.springframework.web.util.NestedServletException:处理程序调度失败;嵌套异常是java.lang.StackOverflowError 这是我的配置文件: AuthorizationServerConfiguration.java @Configuration @EnableAuthorizationServer public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @Autowired DataSource dataSource; @Autowired private UserDetailsService userDetailsService; @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Override public void configure( AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer .tokenKeyAccess("permitAll()") .checkTokenAccess("isAuthenticated()"); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints .tokenStore(tokenStore()) .authenticationManager(authenticationManager); } @Bean public TokenStore tokenStore() { return new JdbcTokenStore(dataSource); } } ResourceServerConfiguration.java @Configuration @EnableResourceServer public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { private String resourceId = "rest-api"; @Override public void configure(ResourceServerSecurityConfigurer resources) { // @formatter:off resources.resourceId(resourceId); // @formatter:on } @Override public void configure(HttpSecurity http) throws Exception { // @formatter:off http.authorizeRequests() .antMatchers(HttpMethod.OPTIONS).permitAll() .anyRequest().authenticated(); // @formatter:on } } WebApplicationInitializer.java public class WebAppInitializer implements WebApplicationInitializer { private Logger logger = LoggerFactory.getLogger(getClass()); @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext rootContext=new AnnotationConfigWebApplicationContext(); rootContext.register(ApplicationRootConfig.class, HibernateConfig.class, AnnotationBasedSecurityConfig.class, GlobalAuthenticationConfig.class, SecurityConfiguration.class, AuthorizationServerConfiguration.class, ResourceServerConfiguration.class); servletContext.addListener(new ContextLoaderListener(rootContext)); servletContext.setInitParameter("defaultHtmlEscape", "true"); FilterRegistration.Dynamic encodingFilter=servletContext.addFilter("encoding-filter", new CharacterEncodingFilter()); encodingFilter.setInitParameter("encoding", "UTF-8"); encodingFilter.setInitParameter("forceEncoding", "true"); encodingFilter.addMappingForServletNames(null, true, "/*"); FilterRegistration.Dynamic securityFilter = servletContext.addFilter("securityFilter",new DelegatingFilterProxy("springSecurityFilterChain")); securityFilter.addMappingForUrlPatterns(null, false,"/*"); servletContext.addListener(new HttpSessionEventPublisher()); ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext)); dispatcher.setLoadOnStartup(1); Set<String> mappingConflicts = dispatcher.addMapping("/"); if(!mappingConflicts.isEmpty()){ for (String map : mappingConflicts) { logger.error("Mapping Conflict "+map); } throw new IllegalStateException("Dispatcher : cannot be mapped to '/' under Tomcat vesions <= 7.0.4"); } rootContext.setServletContext(servletContext); rootContext.refresh(); } } UserDetailsS​​erviceImpl.java @Service @Transactional(readOnly=true) public class UserDetailsServiceImpl implements UserDetailsService{ Logger logger = LoggerFactory.getLogger(UserDetailsServiceImpl.class); @Autowired UserDAO userDAO; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { logger.info("loadUserByUsername "+username); Collection<User> user = userDAO.findByEmail(username); return user.iterator().next(); } } SecurityConfiguration.java @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .formLogin().permitAll(); } } oauth_client_details表 全栈跟踪 2016-10-14 18:05:43 DEBUG o.s.o.h.HibernateTransactionManager - Creating new transaction with name [org.springframework.security.oauth2.provider.token.DefaultTokenServices.createAccessToken]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 2016-10-14 18:05:43 DEBUG o.s.o.h.HibernateTransactionManager - Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=org.hibernate.engine.spi.ExecutableList@1e09a738 updates=org.hibernate.engine.spi.ExecutableList@67d0f9f8 deletions=org.hibernate.engine.spi.ExecutableList@c60ee2d orphanRemovals=org.hibernate.engine.spi.ExecutableList@3bdd7e0f collectionCreations=org.hibernate.engine.spi.ExecutableList@683e2e2b collectionRemovals=org.hibernate.engine.spi.ExecutableList@84115ed collectionUpdates=org.hibernate.engine.spi.ExecutableList@3db934e collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5326b83c unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 2016-10-14 18:05:43 DEBUG o.s.o.h.HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=org.hibernate.engine.spi.ExecutableList@1e09a738 updates=org.hibernate.engine.spi.ExecutableList@67d0f9f8 deletions=org.hibernate.engine.spi.ExecutableList@c60ee2d orphanRemovals=org.hibernate.engine.spi.ExecutableList@3bdd7e0f collectionCreations=org.hibernate.engine.spi.ExecutableList@683e2e2b collectionRemovals=org.hibernate.engine.spi.ExecutableList@84115ed collectionUpdates=org.hibernate.engine.spi.ExecutableList@3db934e collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5326b83c unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 2016-10-14 18:05:43 DEBUG o.s.o.h.HibernateTransactionManager - Exposing Hibernate transaction as JDBC transaction [com.mchange.v2.c3p0.impl.NewProxyConnection@4a1e11db] 2016-10-14 18:05:44 DEBUG o.s.o.h.HibernateTransactionManager - Initiating transaction rollback 2016-10-14 18:05:44 DEBUG o.s.o.h.HibernateTransactionManager - Rolling back Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=org.hibernate.engine.spi.ExecutableList@1e09a738 updates=org.hibernate.engine.spi.ExecutableList@67d0f9f8 deletions=org.hibernate.engine.spi.ExecutableList@c60ee2d orphanRemovals=org.hibernate.engine.spi.ExecutableList@3bdd7e0f collectionCreations=org.hibernate.engine.spi.ExecutableList@683e2e2b collectionRemovals=org.hibernate.engine.spi.ExecutableList@84115ed collectionUpdates=org.hibernate.engine.spi.ExecutableList@3db934e collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5326b83c unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 2016-10-14 18:05:44 DEBUG o.s.o.h.HibernateTransactionManager - Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=org.hibernate.engine.spi.ExecutableList@1e09a738 updates=org.hibernate.engine.spi.ExecutableList@67d0f9f8 deletions=org.hibernate.engine.spi.ExecutableList@c60ee2d orphanRemovals=org.hibernate.engine.spi.ExecutableList@3bdd7e0f collectionCreations=org.hibernate.engine.spi.ExecutableList@683e2e2b collectionRemovals=org.hibernate.engine.spi.ExecutableList@84115ed collectionUpdates=org.hibernate.engine.spi.ExecutableList@3db934e collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5326b83c unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction 2016-10-14 18:05:44 DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.OAuth2AccessToken> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(java.security.Principal,java.util.Map<java.lang.String, java.lang.String>) throws org.springframework.web.HttpRequestMethodNotSupportedException]: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.StackOverflowError 2016-10-14 18:05:44 DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Invoking @ExceptionHandler method: public org.springframework.http.ResponseEntity<org.springframework.security.oauth2.common.exceptions.OAuth2Exception> org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.handleException(java.lang.Exception) throws java.lang.Exception 2016-10-14 18:05:44 INFO o.s.s.o.p.endpoint.TokenEndpoint - Handling error: NestedServletException, Handler dispatch failed; nested exception is java.lang.StackOverflowError 2016-10-14 18:05:44 DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Written [error="server_error", error_description="Handler dispatch failed; nested exception is java.lang.StackOverflowError"] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@120db352] 2016-10-14 18:05:44 DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling 2016-10-14 18:05:44 DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request 2016-10-14 18:05:44 DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'delegatingApplicationListener' 2016-10-14 18:05:44 DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally 2016-10-14 18:05:44 DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed 我是通过使用form-urlencoded和Authorization Basic Auth(客户端详细信息)在body中传递grant_type =“password”,username =“user”,password =“pass”来测试邮递员. User.java @Entity @Table(name="xt_user_profile") public class User extends XtremandTimeStamp implements UserDetails{ @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="user_id_seq") @SequenceGenerator( name="user_id_seq", sequenceName="user_id_seq", allocationSize=1 ) @Column(name="user_id") private Integer userId; @Column(name="user_name") private String userName; @Column(name="email_id") private String emailId; @Column(name="password") private String password; @Column(name="firstname") private String firstName; @Column(name="lastname") private String lastName; @Column(name="status") @org.hibernate.annotations.Type(type="com.xtremand.user.bom.UserStatusType") private UserStatus userStatus; private String country; private String city; private String zip; @Column(name="headline") private String headLine; private String description; @Column(name="googlelogin") private String googleLogin; @Column(name="linkedinlogin") private String linkedinLogin; @Column(name="twitterlogin") private String twitterLogin; @Column(name="facebooklogin") private String facebookLogin; @Column(name="datereg", columnDefinition="DATETIME") @Temporal(TemporalType.TIMESTAMP) private Date dateReg; @Column(name="datelastedit", columnDefinition="DATETIME") @Temporal(TemporalType.TIMESTAMP) private Date dateLastEdit; @Column(name="datelastlogin", columnDefinition="DATETIME") @Temporal(TemporalType.TIMESTAMP) private Date dateLastLogin; @Column(name="datelastnav", columnDefinition="DATETIME") @Temporal(TemporalType.TIMESTAMP) private Date dateLastNav; @Column(name="alias") private String alias; public enum UserStatus{ // UNAPPROVED,APPROVE,DECLINE,BLOCK,SUSPEND,DELETE UAPPROVED("UnApproved"), APPROVED("APPROVED"), DECLINE("DECLINE"), BLOCK("BLOCK"), SUSPEND("SUSPEND"), DELETE("DELETE"); protected String status; private UserStatus(String status) { this.status = status; } public String getStatus() { return status; } } public void initialiseCommonFields(boolean isCreate, int updatedBy){ super.initialiseCommonFields(isCreate, updatedBy); this.setDateLastEdit(new Date()); this.setDateLastLogin(new Date()); this.setDateLastNav(new Date()); this.setDateReg(new Date()); } @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @Fetch(FetchMode.SUBSELECT) @JoinTable(name = "xt_user_role", joinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "role_id", nullable = false, updatable = false) }) private Set<Role> roles = new HashSet<Role>(0); @Fetch(FetchMode.SUBSELECT) @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private Set<UserSubscription> userSubscriptions = new HashSet<UserSubscription>(0); public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getEmailId() { return emailId; } public void setEmailId(String emailId) { this.emailId = emailId; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public UserStatus getUserStatus() { return userStatus; } public void setUserStatus(UserStatus userStatus) { this.userStatus = userStatus; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getZip() { return zip; } public void setZip(String zip) { this.zip = zip; } public String getHeadLine() { return headLine; } public void setHeadLine(String headLine) { this.headLine = headLine; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getGoogleLogin() { return googleLogin; } public void setGoogleLogin(String googleLogin) { this.googleLogin = googleLogin; } public String getLinkedinLogin() { return linkedinLogin; } public void setLinkedinLogin(String linkedinLogin) { this.linkedinLogin = linkedinLogin; } public String getTwitterLogin() { return twitterLogin; } public void setTwitterLogin(String twitterLogin) { this.twitterLogin = twitterLogin; } public String getFacebookLogin() { return facebookLogin; } public void setFacebookLogin(String facebookLogin) { this.facebookLogin = facebookLogin; } public Date getDateReg() { return dateReg; } public void setDateReg(Date dateReg) { this.dateReg = dateReg; } public Date getDateLastEdit() { return dateLastEdit; } public void setDateLastEdit(Date dateLastEdit) { this.dateLastEdit = dateLastEdit; } public Date getDateLastLogin() { return dateLastLogin; } public void setDateLastLogin(Date dateLastLogin) { this.dateLastLogin = dateLastLogin; } public Date getDateLastNav() { return dateLastNav; } public void setDateLastNav(Date dateLastNav) { this.dateLastNav = dateLastNav; } public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getAlias() { return alias; } public void setAlias(String alias) { this.alias = alias; } public Set<UserSubscription> getUserSubscriptions() { return this.userSubscriptions; } public void setUserSubscriptions(Set<UserSubscription> userSubscriptions) { this.userSubscriptions = userSubscriptions; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { // TODO Auto-generated method stub return getRoles(); } @Override public boolean isAccountNonExpired() { // TODO Auto-generated method stub return true; } @Override public boolean isAccountNonLocked() { // TODO Auto-generated method stub return true; } @Override public boolean isCredentialsNonExpired() { // TODO Auto-generated method stub return true; } @Override public boolean isEnabled() { // TODO Auto-generated method stub return true; } @Override public String getUsername() { return getUsername(); } }
...全文
1073 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38067646 2019-09-12
  • 打赏
  • 举报
回复
请尝试添加下一个配置,可能会帮助您: endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST); 这将允许两种授权方法. 并添加: oauthServer.allowFormAuthenticationForClients() // it should allow authorize from form submitting. 还要检查是否为db中的客户端授予了authorizedGrantTypes“password”. 在您的User.class检查方法中: @Override public String getUsername() { return getUsername(); } 它是对自己的引用,当spring尝试获取用户名时引发StackOverflowException.请更改此方法的实现,它将修复StackOverflowException.
代码下载链接: https://pan.quark.cn/s/73799e85b3cd Veeam Backup & Replication 多种备份策略深度解析Veeam Backup & Replication 是一款具备高度功能性与适应性的备份工具,其内置了多样化的备份选项,旨在适应不同环境下对数据保护的需求。本文将全面阐释Veeam Backup & Replication中所包含的几种备份策略,涵盖正向的永久增量策略、正向的增量策略、逆向的增量策略、动态的全面策略以及整合的全面策略。1. 正向的永久增量策略(Forward Incremental-Forever Strategy)正向的永久增量策略是一种预设的备份模式,其会构建一个备份序列,该序列由初次执行的全面备份及后续一系列正向增量备份组合而成。此备份策略的长处在于能够有效缩短备份周期并节约存储容量。在初次备份任务启动时,Veeam Backup & Replication会在备份存储库中创建.vbk格式的全面备份文档。在随后的备份任务中,Veeam Backup & Replication会复制自上一次备份任务至当前时间点增加的虚拟机数据单元,并将这些数据单元作为一个.vib格式的增量备份文档存入备份序列。2. 正向的增量策略(Forward Incremental Strategy)正向的增量策略同样会构建一个备份序列,该序列由初次执行的全面备份及后续一系列正向增量备份构成。与正向的永久增量策略相异之处在于,正向的增量策略还涉及综合性的或动态的全面备份,这些备份将备份序列分割为若干个更小的部分。3. 逆向的增量策略(Reverse Incremental Strategy)逆向的增量策略会生成...

477

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧