Spring security oauth2 java config - handler failed; The nested exception is java.lang.StackOverflowError

Spring Security is configured with OAuth2 in java config, and the client_credentails thread is working fine, but the password thread is being thrown. Sending handler failed; nested exception: java.lang.StackOverflowError below - log information

2016-10-10 23:19:08 DEBUG oswsmmaExceptionHandlerExceptionResolver - 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

here are my configuration files:

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(); } } 

UserDetailsServiceImpl.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 table

oauth_client_details table

Full stack trace

 2016-10-14 18:05:43 DEBUG osohHibernateTransactionManager - Creating new transaction with name [org.springframework.security.oauth2.provider.token.DefaultTokenServices.createAccessToken]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 2016-10-14 18:05:43 DEBUG osohHibernateTransactionManager - 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@683e 2e2b collectionRemovals=org.hibernate.engine.spi.ExecutableList@84115 ed collectionUpdates=org.hibernate.engine.spi.ExecutableList@3db934 e collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5326 b83c unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 2016-10-14 18:05:43 DEBUG osohHibernateTransactionManager - 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@683e 2e2b collectionRemovals=org.hibernate.engine.spi.ExecutableList@84115 ed collectionUpdates=org.hibernate.engine.spi.ExecutableList@3db934 e collectionQueuedOps=org.hibernate.engine.spi.Execu tableList@5326b83c unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 2016-10-14 18:05:43 DEBUG osohHibernateTransactionManager - Exposing Hibernate transaction as JDBC transaction [ com.mchange.v2.c3p0.impl.NewProxyConnection@4a1e11db ] 2016-10-14 18:05:44 DEBUG osohHibernateTransactionManager - Initiating transaction rollback 2016-10-14 18:05:44 DEBUG osohHibernateTransactionManager - 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@683e 2e2b co llectionRemovals=org.hibernate.engine.spi.ExecutableList@84115ed collectionUpdates=org.hibernate.engine.spi.ExecutableList@3db934 e collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5326 b83c unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 2016-10-14 18:05:44 DEBUG osohHibernateTransactionManager - 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@683e 2e2b collectionRemovals=org.hibernate.engine.spi.ExecutableList@84115 ed collectionUpdates=org.hibernate.engine.spi.ExecutableList@3db934 e collectionQueuedOps=org.hibernate.engine.spi.ExecutableList@5326 b83c unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction 2016-10-14 18:05:44 DEBUG oswsmmaExceptionHandlerExceptionResolver - 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 oswsmmaExceptionHandlerExceptionResolver - 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 ossopendpoint.TokenEndpoint - Handling error: NestedServletException, Handler dispatch failed; nested exception is java.lang.StackOverflowError 2016-10-14 18:05:44 DEBUG oswsmmaHttpEntityMethodProcessor - Written [error="server_error", error_description="Handler dispatch failed; nested exception is java.lang.StackOverflowError"] as "application/json" using [org.springfr amework.http.converter.json.MappingJackson2HttpMessageConverter@ 120db352] 2016-10-14 18:05:44 DEBUG osweb.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling 2016-10-14 18:05:44 DEBUG osweb.servlet.DispatcherServlet - Successfully completed request 2016-10-14 18:05:44 DEBUG osbfsDefaultListableBeanFactory - Returning cached instance of singleton bean 'delegatingApplicationListener' 2016-10-14 18:05:44 DEBUG osswaExceptionTranslationFilter - Chain processed normally 2016-10-14 18:05:44 DEBUG osswcSecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed 

Testing from the postman by passing grant_type = "password", username = "user", password = "pass" in the body with the form-urlencoded and Basic Auth authentication (client information).

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(); } } 
+5
source share
1 answer

Please try adding the following configuration that may help you:

 endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST); 

This will allow you to use both authorization methods.

And add:

 oauthServer.allowFormAuthenticationForClients() // it should allow authorize from form submitting. 

Also check that you have provided authorized GrantTypes "password" for your clients in db.

In your User.class validation method:

 @Override public String getUsername() { return getUsername(); } 

it refers to itself, and when spring tries to get the username, raise a StackOverflowException. Please change the implementation of this method, it will fix your StackOverflowException.

+2
source

Source: https://habr.com/ru/post/1258002/


All Articles