Я создал службу поддержки Java EE 6 restfull и попытался интегрировать ее с Spring Security. Но все время я получаю разные странные исключения. Что не имеет никакого смысла или может иметь смысл, но, по крайней мере, не для меня.Spring Security с Java EE Restful Service
структура Направление моего приложения что-то вроде этого:
com.security
UserDetailsSecurityConfig.java
com.service
ApplicationConfig.java
UserFacadeREST.java
com.config
AppConfig.java
Мои объекты сгенерированы автоматически поэтому ошибка не кажется, чтобы быть там. Но, да, три файла кажутся мне подозрительными, поскольку UserFacadeREST отлично работает, когда я не интегрирую свое приложение с 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();
}
}
В целом коде я сделал несколько изменений для попадания и суда. И в настоящее время я получаю исключение.
java.lang.IllegalStateException: Нет WebApplicationContext найдено: нет ContextLoaderListener зарегистрирован?
Перед тем, что я получаю еще одно исключение, которое было
WebSecurityConfigurers должен быть уникальным. Заказ 100 был уже использован
Я не понимаю, что я делаю неправильно в интеграции Spring Security с Java EE 6. Я новичок в Spring, возможно, я делаю ошибку, которая кажется мне очевидной.
Мой файл web.xml является:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
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>
Я сделал изменение и все еще получаю то же исключение. Я также просмотрел код и не нашел несколько записей в WebSecurityCOnfigurerAdapter. Но после применения этого изменения исключение немного изменилось: java.lang.IllegalStateException: нет обнаруженного WebApplicationContext: инициализатор не зарегистрирован? –
Зачем вам нужен 'DispatcherServlet'? Может быть, вам просто нужно использовать 'ContextLoaderListener'? Я думаю, что Джерси 2 пытается сделать это за вас, поэтому, возможно, это проблема (Джерси загрузил контекст Spring для вас, а затем снова загрузил его)? –
P.S. Я сказал вам поставить init-param в неправильном месте (он идет в фильтре). См. Обновленный ответ. Но если вам не нужен сервлет, тогда совет меняется. –