mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-02 19:27:57 +08:00
PL-6730 REST API should work in portal module; Some URL configurations from the rest-api-security-spring.xml are extracted to the app properties; jackson dependency added; Portal spring context is now a root web spring context
This commit is contained in:
parent
4d46afca65
commit
e34d41f164
@ -741,6 +741,8 @@ configure(restApiModule) {
|
||||
compile(group: 'org.springframework', name: 'spring-webmvc', version: springVersion)
|
||||
compile(group: 'org.springframework', name: 'spring-context-support', version: springVersion)
|
||||
compile(group: 'org.json', name: 'json', version: '20140107')
|
||||
compile(group: 'com.fasterxml.jackson.core', name:'jackson-databind', version: '2.8.0')
|
||||
|
||||
compile(groovyArtifact)
|
||||
|
||||
compile(group: 'org.springframework.security', name: 'spring-security-core', version: springSecurityVersion)
|
||||
|
@ -86,7 +86,7 @@ public class AppContextLoader extends AbstractWebAppContextLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassPathXmlApplicationContext createClassPathXmlApplicationContext(String[] locations) {
|
||||
protected ClassPathXmlApplicationContext createApplicationContext(String[] locations) {
|
||||
return new CubaCoreApplicationContext(locations);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public class SingleAppCoreContextLoader extends AppContextLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassPathXmlApplicationContext createClassPathXmlApplicationContext(String[] locations) {
|
||||
protected ClassPathXmlApplicationContext createApplicationContext(String[] locations) {
|
||||
return new CubaCoreApplicationContext(locations) {
|
||||
/**
|
||||
* Here we create resource resolver which scans only core jars (and avoid putting web beans to core context)
|
||||
|
@ -45,7 +45,8 @@
|
||||
<module name="rest-api" dependsOn="client" blocks="web,portal">
|
||||
<artifact name="cuba-rest-api" appJar="true"/>
|
||||
|
||||
<property name="cuba.dispatcherSpringContextConfig" value="rest-api-security-spring.xml"/>
|
||||
<property name="cuba.springContextConfig" value="rest-api-security-spring.xml"/>
|
||||
<property name="cuba.dispatcherSpringContextConfig" value="rest-api-dispatcher-spring.xml"/>
|
||||
</module>
|
||||
|
||||
<module name="gui" dependsOn="client" blocks="web,desktop">
|
||||
|
@ -20,6 +20,7 @@ package com.haulmont.cuba.core.sys;
|
||||
import com.haulmont.cuba.core.sys.persistence.EclipseLinkCustomizer;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.text.StrTokenizer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
@ -52,7 +53,7 @@ public abstract class AbstractAppContextLoader {
|
||||
String[] locations = tokenizer.getTokenArray();
|
||||
replaceLocationsFromConf(locations);
|
||||
|
||||
ClassPathXmlApplicationContext appContext = createClassPathXmlApplicationContext(locations);
|
||||
ApplicationContext appContext = createApplicationContext(locations);
|
||||
AppContext.Internals.setApplicationContext(appContext);
|
||||
}
|
||||
|
||||
@ -74,7 +75,7 @@ public abstract class AbstractAppContextLoader {
|
||||
}
|
||||
}
|
||||
|
||||
protected ClassPathXmlApplicationContext createClassPathXmlApplicationContext(String[] locations) {
|
||||
protected ApplicationContext createApplicationContext(String[] locations) {
|
||||
return new CubaClassPathXmlApplicationContext(locations);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,12 @@ package com.haulmont.cuba.portal.sys;
|
||||
import com.haulmont.cuba.core.global.ClientType;
|
||||
import com.haulmont.cuba.core.sys.AbstractWebAppContextLoader;
|
||||
import com.haulmont.cuba.core.sys.AppContext;
|
||||
import com.haulmont.cuba.core.sys.CubaXmlWebApplicationContext;
|
||||
import com.haulmont.cuba.core.sys.ServletContextHolder;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
/**
|
||||
* {@link AppContext} loader of the web portal client application.
|
||||
@ -38,4 +44,25 @@ public class PortalAppContextLoader extends AbstractWebAppContextLoader {
|
||||
|
||||
AppContext.setProperty("cuba.clientType", ClientType.PORTAL.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ApplicationContext createApplicationContext(String[] locations) {
|
||||
CubaXmlWebApplicationContext webContext = new CubaXmlWebApplicationContext();
|
||||
String[] classPathLocations = new String[locations.length];
|
||||
for (int i = 0; i < locations.length; i++) {
|
||||
classPathLocations[i] = "classpath:" + locations[i];
|
||||
}
|
||||
webContext.setConfigLocations(classPathLocations);
|
||||
webContext.setServletContext(ServletContextHolder.getServletContext());
|
||||
webContext.refresh();
|
||||
|
||||
ServletContext servletContext = ServletContextHolder.getServletContext();
|
||||
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot initialize context because there is already a root application context present - " +
|
||||
"check whether you have multiple ContextLoader* definitions in your web.xml!");
|
||||
}
|
||||
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, webContext);
|
||||
return webContext;
|
||||
}
|
||||
}
|
||||
|
@ -59,4 +59,19 @@ cuba.mainMessagePack=com.haulmont.cuba.core
|
||||
cuba.groovyClassPath=
|
||||
cuba.groovyEvaluatorImport=com.haulmont.cuba.core.global.PersistenceHelper
|
||||
|
||||
cuba.passwordEncryptionModule=cuba_Sha1EncryptionModule
|
||||
cuba.passwordEncryptionModule=cuba_Sha1EncryptionModule
|
||||
|
||||
###############################################################################
|
||||
# REST API #
|
||||
###############################################################################
|
||||
|
||||
cuba.rest.url.oauthPattern=/api/oauth/**
|
||||
cuba.rest.url.apiPattern=/api/**
|
||||
cuba.rest.url.oauthToken=/api/oauth/token
|
||||
|
||||
# Credentials for REST API client
|
||||
cuba.rest.client.id=client
|
||||
cuba.rest.client.secret=secret
|
||||
|
||||
# A token expiration time in seconds for the default client (12 hours)
|
||||
cuba.rest.client.tokenExpirationTimeSec=43200
|
@ -30,7 +30,6 @@ import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
*/
|
||||
@Component
|
||||
public class OAuthTokenRevoker {
|
||||
private static final Logger log = LoggerFactory.getLogger(OAuthTokenRevoker.class);
|
||||
|
||||
|
@ -32,8 +32,7 @@ import java.util.UUID;
|
||||
|
||||
/**
|
||||
*/
|
||||
@Component
|
||||
public class ParseUtils {
|
||||
public class RestParseUtils {
|
||||
|
||||
@Inject
|
||||
protected EntitySerializationAPI entitySerializationAPI;
|
@ -42,7 +42,6 @@ import java.util.stream.Collectors;
|
||||
* Class is used for loading and storing of predefined JPQL queries that are used by the REST API.
|
||||
* Queries are loaded from configuration files defined by the {@code cuba.rest.queriesConfig} application property.
|
||||
*/
|
||||
@Component("cuba_RestQueriesManager")
|
||||
public class RestQueriesManager {
|
||||
|
||||
protected final String CUBA_REST_QUERIES_CONFIG_PROP_NAME = "cuba.rest.queriesConfig";
|
||||
|
@ -25,10 +25,9 @@ import com.haulmont.chile.core.datatypes.Datatypes;
|
||||
import com.haulmont.cuba.core.app.serialization.EntitySerializationAPI;
|
||||
import com.haulmont.cuba.core.entity.Entity;
|
||||
import com.haulmont.cuba.core.global.AppBeans;
|
||||
import com.haulmont.restapi.common.ParseUtils;
|
||||
import com.haulmont.restapi.common.RestParseUtils;
|
||||
import com.haulmont.restapi.exception.RestAPIException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -42,11 +41,10 @@ import java.util.Map;
|
||||
/**
|
||||
* Class is used for invoking middleware services from REST API service controller
|
||||
*/
|
||||
@Component
|
||||
public class RestServiceInvoker {
|
||||
|
||||
@Inject
|
||||
protected ParseUtils parseUtils;
|
||||
protected RestParseUtils restParseUtils;
|
||||
|
||||
@Inject
|
||||
protected EntitySerializationAPI entitySerializationAPI;
|
||||
@ -86,7 +84,7 @@ public class RestServiceInvoker {
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
Class<?> aClass = types[i];
|
||||
try {
|
||||
paramValues.add(parseUtils.toObject(aClass, paramValuesStr.get(i)));
|
||||
paramValues.add(restParseUtils.toObject(aClass, paramValuesStr.get(i)));
|
||||
} catch (ParseException e) {
|
||||
throw new RestAPIException("Invalid parameter value",
|
||||
e.getMessage(),
|
||||
|
33
modules/rest-api/src/rest-api-dispatcher-spring.xml
Normal file
33
modules/rest-api/src/rest-api-dispatcher-spring.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2008-2016 Haulmont.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-4.2.xsd
|
||||
http://www.springframework.org/schema/mvc
|
||||
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||
|
||||
<context:annotation-config/>
|
||||
<context:component-scan base-package="com.haulmont.restapi.controllers"/>
|
||||
|
||||
</beans>
|
@ -31,10 +31,17 @@
|
||||
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
|
||||
|
||||
<context:annotation-config/>
|
||||
<context:component-scan base-package="com.haulmont.restapi"/>
|
||||
|
||||
<bean class="com.haulmont.cuba.core.sys.CubaPropertyPlaceholderConfigurer"/>
|
||||
|
||||
<!-- Module beans -->
|
||||
<bean id="cuba_OAuthTokenRevoker" class="com.haulmont.restapi.auth.OAuthTokenRevoker"/>
|
||||
<bean id="cuba_RestQueriesManager" class="com.haulmont.restapi.query.RestQueriesManager"/>
|
||||
<bean id="cuba_RestServiceInvoker" class="com.haulmont.restapi.service.RestServiceInvoker"/>
|
||||
<bean id="cuba_RestParseUtils" class="com.haulmont.restapi.common.RestParseUtils"/>
|
||||
|
||||
<!-- According to the spec the token endpoint should be secured by the basic authentication -->
|
||||
<http pattern="/dispatch/api/oauth/**"
|
||||
<http pattern="${cuba.rest.url.oauthPattern}"
|
||||
create-session="stateless"
|
||||
authentication-manager-ref="clientAuthenticationManager"
|
||||
xmlns="http://www.springframework.org/schema/security">
|
||||
@ -43,6 +50,8 @@
|
||||
<csrf disabled="true"/>
|
||||
</http>
|
||||
|
||||
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"/>
|
||||
|
||||
<!-- Authentication manager that is used by token endpoint. Checks client credentials in http header -->
|
||||
<security:authentication-manager id="clientAuthenticationManager">
|
||||
<security:authentication-provider user-service-ref="clientDetailsUserDetailsService"/>
|
||||
@ -56,26 +65,27 @@
|
||||
accessing the auth token -->
|
||||
<oauth2:client-details-service id="clientDetailsService">
|
||||
<oauth2:client
|
||||
client-id="client"
|
||||
secret="secret"
|
||||
client-id="${cuba.rest.client.id}"
|
||||
secret="${cuba.rest.client.secret}"
|
||||
access-token-validity="${cuba.rest.client.tokenExpirationTimeSec}"
|
||||
authorized-grant-types="password"
|
||||
scope="rest-api"/>
|
||||
</oauth2:client-details-service>
|
||||
|
||||
<!-- Specifies token endpoint.-->
|
||||
<oauth2:authorization-server
|
||||
token-endpoint-url="/api/oauth/token"
|
||||
token-endpoint-url="${cuba.rest.url.oauthToken}"
|
||||
client-details-service-ref="clientDetailsService"
|
||||
token-services-ref="tokenServices" >
|
||||
<oauth2:password authentication-manager-ref="userAuthenticationManager"/>
|
||||
</oauth2:authorization-server>
|
||||
|
||||
<bean id="userAuthenticationProvider" class="com.haulmont.restapi.auth.CubaUserAuthenticationProvider"/>
|
||||
|
||||
<security:authentication-manager alias="userAuthenticationManager">
|
||||
<security:authentication-provider ref="userAuthenticationProvider"/>
|
||||
</security:authentication-manager>
|
||||
|
||||
<bean id="userAuthenticationProvider" class="com.haulmont.restapi.auth.CubaUserAuthenticationProvider"/>
|
||||
|
||||
<!--todo MG try to remove clientDetailsService-->
|
||||
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
|
||||
<property name="tokenStore" ref="tokenStore"/>
|
||||
@ -86,27 +96,24 @@
|
||||
|
||||
<oauth2:resource-server id="resourceFilter" token-services-ref="tokenServices" />
|
||||
|
||||
<http pattern="/dispatch/api/**"
|
||||
<!--todo MG remove hasRole check-->
|
||||
<http pattern="${cuba.rest.url.apiPattern}"
|
||||
create-session="stateless"
|
||||
entry-point-ref="oauthAuthenticationEntryPoint"
|
||||
xmlns="http://www.springframework.org/schema/security">
|
||||
<intercept-url pattern="/dispatch/api/entities/**" access="hasRole('USER')"/>
|
||||
<intercept-url pattern="/dispatch/api/queries/**" access="hasRole('USER')"/>
|
||||
<intercept-url pattern="/dispatch/api/services/**" access="hasRole('USER')"/>
|
||||
<intercept-url pattern="/**" access="hasRole('USER')"/>
|
||||
<anonymous enabled="false"/>
|
||||
<csrf disabled="true"/>
|
||||
<custom-filter ref="resourceFilter" before="PRE_AUTH_FILTER"/>
|
||||
</http>
|
||||
|
||||
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"/>
|
||||
|
||||
<bean id="clientCredentialsTokenEndpointFilter"
|
||||
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
|
||||
<property name="authenticationManager" ref="clientAuthenticationManager"/>
|
||||
</bean>
|
||||
<!--<bean id="clientCredentialsTokenEndpointFilter"-->
|
||||
<!--class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">-->
|
||||
<!--<property name="authenticationManager" ref="clientAuthenticationManager"/>-->
|
||||
<!--</bean>-->
|
||||
|
||||
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
|
||||
<property name="realmName" value="test" />
|
||||
<property name="realmName" value="rest-api" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
@ -100,7 +100,7 @@ public class SingleAppWebContextLoader extends WebAppContextLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassPathXmlApplicationContext createClassPathXmlApplicationContext(String[] locations) {
|
||||
protected ClassPathXmlApplicationContext createApplicationContext(String[] locations) {
|
||||
return new CubaClassPathXmlApplicationContext(locations) {
|
||||
/**
|
||||
* Here we create resource resolver which scans only web jars (and avoid putting core beans to web context)
|
||||
|
@ -89,4 +89,19 @@ cuba.web.loginDialogDefaultPassword=admin
|
||||
com.vaadin.terminal.gwt.server.productionMode=false
|
||||
|
||||
# Enable Testing mode: true or false (by default)
|
||||
cuba.testMode=false
|
||||
cuba.testMode=false
|
||||
|
||||
###############################################################################
|
||||
# REST API #
|
||||
###############################################################################
|
||||
|
||||
cuba.rest.url.oauthPattern=/dispatch/api/oauth/**
|
||||
cuba.rest.url.apiPattern=/dispatch/api/**
|
||||
cuba.rest.url.oauthToken=/api/oauth/token
|
||||
|
||||
# Credentials for REST API client
|
||||
cuba.rest.client.id=client
|
||||
cuba.rest.client.secret=secret
|
||||
|
||||
# A token expiration time in seconds for the default client (12 hours)
|
||||
cuba.rest.client.tokenExpirationTimeSec=43200
|
Loading…
Reference in New Issue
Block a user