vendredi 27 février 2015

Spring Security with Java EE Restful Service

I have created a Java EE 6 restfull service and tried to integrate that with Spring Security. But, all the time I get different weird exceptions. Which doesn't make any sense or may be make sense but at least not for me.


Direction structure of my application is something like this:



com.security
UserDetailsSecurityConfig.java
com.service
ApplicationConfig.java
UserFacadeREST.java
com.config
AppConfig.java


My entities are auto generated so no error seems to be there. But, yes the three files seems fishy to me as UserFacadeREST is working fine when I don't integrate my application with Spring Security.



com.UserDetailsSecurityConfig.java




@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class UserDetailsSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService( userDetailsService() );
}
@Override
protected void configure( HttpSecurity http ) throws Exception {
http
.httpBasic().and()
.sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS ).and()
.authorizeRequests().antMatchers("/**").hasRole( "USER" );
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsService() {
@Override
public UserDetails loadUserByUsername( final String username )
throws UsernameNotFoundException {
if( username.equals( "admin" ) ) {
return new User( username, "password", true, true, true, true,
Arrays.asList(
new SimpleGrantedAuthority("ROLE_USER" ),
new SimpleGrantedAuthority( "ROLE_ADMIN" )
)
);
} else if ( username.equals( "user" ) ) {
return new User( username, "password", true, true, true, true,
Arrays.asList(
new SimpleGrantedAuthority( "ROLE_USER" )
)
);
}

return null;
}
};
}

}



com.service.ApplicationConfig.java




@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationConfig extends Application {

@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new java.util.HashSet<>();
addRestResourceClasses(resources);
return resources;
}

/**
* Do not modify addRestResourceClasses() method.
* It is automatically populated with
* all resources defined in the project.
* If required, comment out calling this method in getClasses().
*/
private void addRestResourceClasses(Set<Class<?>> resources) {
resources.add(com.service.UserFacadeREST.class);
}

}



com.service.UserFacadeREST.java




@Stateless
@Path("user")
public class UserFacadeREST extends AbstractFacade<UpUser> {
@PersistenceContext(unitName = "PU")
private EntityManager em;

public UserFacadeREST() {
super(User.class);
}

@POST
@Override
@Consumes({"application/xml", "application/json"})
public void create(User entity) {
super.create(entity);
}
@GET
@Path("count")
@Produces("text/plain")
public String countREST() {
return String.valueOf(super.count());
}

}



com.config.AppConfig.java




@Configuration
@Import( UserDetailsSecurityConfig.class )
public class AppConfig {
@Bean
public ApplicationConfig applicationConfig() {
return new ApplicationConfig();
}
@Bean
public UserFacadeREST userRestService() {
return new UserFacadeREST();
}


}


In whole code I have made few changes for hit and trial. And currently, I am getting an exception.



java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?



Before that I was getting another exception which was



WebSecurityConfigurers must be unique. Order of 100 was already used



I am not getting what I am doing wrong in integrating Spring Security with Java EE 6. I am new to Spring so may be I am doing a blunder which seems obvious to me.


My web.xml file is:



<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://ift.tt/nSRXKP"
xmlns:web="http://ift.tt/1eWqHMP"
xmlns:xsi="http://ift.tt/ra1lAU"
xsi:schemaLocation="http://ift.tt/nSRXKP http://ift.tt/1eWqHMP"
id="rest-sec" version="3.0">

<display-name>rest</display-name>

<!-- Spring security -->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>etagFilter</filter-name>
<filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>etagFilter</filter-name>
<url-pattern>/api/*</url-pattern>
</filter-mapping>

<!-- rest -->
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.labs.entities</param-value> <!-- won't find anything -->
</init-param>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>

<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>

<!-- Disables servlet container welcome file handling. Needed for compatibility
with Servlet 3.0 and Tomcat 7.0 -->
<welcome-file-list>
<welcome-file />
</welcome-file-list>

</web-app>

Aucun commentaire:

Enregistrer un commentaire