Skip to content

Commit

Permalink
georchestra#37: security integration (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbarto committed Oct 16, 2019
1 parent adfe84f commit 2ced7fb
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 4 deletions.
19 changes: 16 additions & 3 deletions js/app.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const assign = require('object-assign');
/**
* Copyright 2016, GeoSolutions Sas.
* All rights reserved.
Expand Down Expand Up @@ -37,13 +38,25 @@ ConfigUtils.setLocalConfigurationFile('MapStore2/web/client/localConfig.json');
* }]
* });
*/
const appConfig = require('@mapstore/product/appConfig');

const appConfig = assign({}, require('@mapstore/product/appConfig'), {
pages: [{
name: "mapviewer",
path: "/",
component: require('@mapstore/product/pages/MapViewer')
}]
});
/**
* Define a custom list of plugins with:
*
* const plugins = require('./plugins');
*/
const plugins = require('@mapstore/product/plugins');
const appPlugins = {
plugins: {
...plugins.plugins,
LoginPlugin: require('./plugins/Login').default
},
requires: plugins.requires
};

require('@mapstore/product/main')(appConfig, plugins);
require('@mapstore/product/main')(appConfig, appPlugins);
25 changes: 25 additions & 0 deletions js/components/User.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import loadingState from "@mapstore/components/misc/enhancers/loadingState";
const UserInfo = ({user}) => <span>{user.name}</span>;
const LoadingUser = loadingState(({ user }) => !user)(UserInfo);
class User extends Component {
static propTypes = {
className: PropTypes.string,
onLogin: PropTypes.func,
user: PropTypes.object
};
componentDidMount() {
if (!this.props.user) {
this.props.onLogin("", "");
}
}
render() {
const {className, ...props} = this.props;
return <div className={className}><LoadingUser {...props} /></div>;
}
}

export const Empty = () => <span/>;

export default User;
29 changes: 29 additions & 0 deletions js/plugins/Login.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {createPlugin} from "@mapstore/utils/PluginsUtils";
import {login} from "@mapstore/actions/security";
import {connect} from "react-redux";
import User, {Empty} from "../components/User";
import security from "@mapstore/reducers/security";

const Login = connect((state) => ({
user: state.security && state.security.user,
bsStyle: "primary",
className: "square-button"
}), {
onLogin: login
})(User);


export default createPlugin('Login', {
component: Empty,
containers: {
OmniBar: {
name: "login",
position: 3,
tool: Login,
priority: 1
}
},
reducers: {
security
}
});
2 changes: 1 addition & 1 deletion web/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<dependency>
<groupId>it.geosolutions.geostore</groupId>
<artifactId>geostore-webapp</artifactId>
<version>1.4.2-SNAPSHOT</version>
<version>1.4.3-SNAPSHOT</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
Expand Down
138 changes: 138 additions & 0 deletions web/src/main/resources/geostore-spring-security.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<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:security="http://www.springframework.org/schema/security"

xmlns:cxf="http://cxf.apache.org/core" xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"

xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
default-autowire="byName">

<!-- ==================================================================== -->
<!-- === REST Security ================================================== -->
<!-- ==================================================================== -->
<security:global-method-security secured-annotations="enabled" />

<security:http auto-config="true" create-session="never" >
<security:http-basic entry-point-ref="restAuthenticationEntryPoint"/>
<!--security:custom-filter ref="authenticationTokenProcessingFilter" before="FORM_LOGIN_FILTER"/-->
<security:custom-filter ref="sessionTokenProcessingFilter" after="FORM_LOGIN_FILTER"/>
<security:custom-filter ref="headersProcessingFilter" before="FORM_LOGIN_FILTER"/>
<security:anonymous />
</security:http>
<!-- Entry point -->
<bean id="restAuthenticationEntryPoint" class="it.geosolutions.geostore.services.rest.security.RestAuthenticationEntryPoint" >
<property name="realmName" value="GeoStore"></property>
</bean>
<!-- GeoStore Auth Provider -->
<bean id="geoStoreUserServiceAuthenticationProvider"
class="it.geosolutions.geostore.services.rest.security.UserServiceAuthenticationProvider">
</bean>

<!-- GeOrchestra header based Auth Provider -->
<bean id="georchestraAuthenticationProvider"
class="it.geosolutions.geostore.services.rest.security.PreAuthenticatedAuthenticationProvider">
</bean>

<bean class="it.geosolutions.geostore.services.rest.security.UserAttributeTokenAuthenticationFilter"
id="authenticationTokenProcessingFilter">
</bean>

<bean class="it.geosolutions.geostore.services.rest.security.SessionTokenAuthenticationFilter"
id="sessionTokenProcessingFilter">
<property name="validateUserFromService" value="false"/>
</bean>

<!-- GeOrchestra header based Auth Filter -->
<bean class="it.geosolutions.geostore.services.rest.security.HeadersAuthenticationFilter"
id="headersProcessingFilter">
</bean>

<!-- bean class="it.geosolutions.geostore.services.rest.security.WebServiceTokenAuthenticationFilter"
id="authenticationTokenProcessingFilter">
<constructor-arg><value>http://localhost:8080/geoserver/www/{token}.txt</value></constructor-arg>
</bean-->

<!-- Inject into the Authentication Manager the GeoStore Auth Provider -->
<security:authentication-manager>
<security:authentication-provider ref='georchestraAuthenticationProvider' />
<!--security:authentication-provider ref='geoStoreUserServiceAuthenticationProvider' /-->
<!-- security:authentication-provider ref='geostoreLdapProvider' / -->
</security:authentication-manager>

<!-- LDAP Auth Provider -->
<!-- Simple namespace-based configuration -->

<!-- Starts an internal LDAP server -->
<!-- security:ldap-server ldif="classpath*:users.ldif" port="33389" root="${ldap.root}"/ -->

<!-- security:authentication-manager>
<security:ldap-authentication-provider
user-search-filter="(uid={0})"
user-search-base="ou=people"
group-search-filter="(member={0})"
group-search-base="ou=groups"
group-role-attribute="cn"
role-prefix="ROLE_">
</security:ldap-authentication-provider>
<security:authentication-provider ref='geostoreLdapProvider' />
</security:authentication-manager -->

<!-- Traditional Bean version of the same configuration -->

<!-- This bean points at the embedded directory server created by the ldap-server element above -->
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://${ldap.host}:${ldap.port}/${ldap.root}" />
</bean>

<!--
<bean id="ldapInitializer" class="it.geosolutions.geostore.init.LDAPInit" lazy-init="false">
<constructor-arg ref="geostoreLdapProvider" />
</bean>
-->

<bean id="geostoreLdapProvider"
class="it.geosolutions.geostore.services.rest.security.UserLdapAuthenticationProvider">
<constructor-arg>
<bean
class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource" />
<property name="userSearch">
<bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg index="0" value="ou=people" />
<constructor-arg index="1" value="(uid={0})" />
<constructor-arg index="2" ref="contextSource" />
</bean>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean
class="it.geosolutions.geostore.services.rest.security.GeoStoreLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource" />
<!-- groupSearchBase -->
<constructor-arg value="ou=groups" />
<!-- roleSearchBase -->
<constructor-arg value="ou=roles" />
<property name="groupSearchFilter" value="(lrGroupOccupant={0})" />
<property name="roleSearchFilter" value="(roleOccupant={0})" />
<!-- the GeoStore convetion is:
* Groups starting with 'ROLE_' will be threated as Auth Roles
* Groups starting withOUT 'ROLE_' will be threated as Groups
-->
<property name="rolePrefix" value="ROLE_" />
<property name="searchSubtree" value="true" />
<property name="convertToUpperCase" value="true" />
</bean>
</constructor-arg>
</bean>

</beans>
34 changes: 34 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,39 @@ module.exports = require('./MapStore2/build/buildConfig')(
{
"@mapstore": path.resolve(__dirname, "MapStore2", "web", "client"),
"@js": path.resolve(__dirname, "js")
},
{
'/rest/geostore': {
target: "http://localhost:8080/mapstore",
secure: false,
headers: {
host: "localhost:8080"
}
},
'/pdf': {
target: "http://localhost:8080/mapstore",
secure: false,
headers: {
host: "localhost:8080"
}
},
'/mapstore/pdf': {
target: "http://localhost:8080",
secure: false,
headers: {
host: "localhost:8080"
}
},
'/proxy': {
target: "http://localhost:8080/mapstore",
secure: false,
headers: {
host: "localhost:8080"
}
},
'/docs': {
target: "http://localhost:8081",
pathRewrite: { '/docs': '/mapstore/docs' }
}
}
);

0 comments on commit 2ced7fb

Please sign in to comment.