Hi Oleg,

I just checked my config (I still like xml-config):


This is how I initialize Spring Security:

<!--
    This config depends on a security context repository being available 
somewhere.
-->
<security:http use-expressions="true" 
security-context-repository-ref="securityContextRepository">
    <security:csrf disabled="true"/>
    <security:form-login login-page="/index.html"/>
    <security:logout/>
    <security:anonymous/>
    <!--
        Session fixation protection would invalidate the old session upon login.
        This would break our ability to log-in several Flex clients in one 
session.
    -->
    <security:session-management session-fixation-protection="none"/>
</security:http>

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider user-service-ref="userDetailsService">
        <security:password-encoder hash="sha">
            <security:salt-source user-property="salt"/>
        </security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>

userDetailsService is a Bean implementing this interface:

org.springframework.security.core.userdetails.UserDetailsService

I needed to configure the message broker with per-client-authentication, by the 
"secured" we turn

<flex:message-broker id="_messageBroker" 
services-config-path="classpath:/META-INF/flex/services-config.xml">
    <flex:secured per-client-authentication="true"/>
</flex:message-broker>

In order to tell Spring Security about blazeDS I used this:

<!-- This is used by spring-security -->
<bean id="securityContextRepository"
      
class="org.springframework.security.web.context.HybridBlazeDSClientHttpSessionSecurityContextRepository">
    <constructor-arg ref="_messageBroker"/>
</bean>

This is a custom class from my side, that I needed to place in the official 
Spring packages in order to use some of the classes and properties:

package org.springframework.security.web.context;

import flex.messaging.MessageBroker;
import flex.messaging.client.FlexClient;
import flex.messaging.client.FlexClientManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextImpl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Created with IntelliJ IDEA.
 * User: cdutz
 * Date: 10.04.12
 * Time: 11:11
 */
public class HybridBlazeDSClientHttpSessionSecurityContextRepository
        extends HttpSessionSecurityContextRepository {

    // This constant will be used in spring bean id="ucgConstants" !!
    public static final String FLEX_CLIENT_ID_PARAMETER = "flexClientId";

    public static final String USED_FLEX_CLIENT = "usedFlexClient";

    private MessageBroker messageBroker;

    public 
HybridBlazeDSClientHttpSessionSecurityContextRepository(MessageBroker 
messageBroker) {
        this.messageBroker = messageBroker;
    }

    @Override
    public SecurityContext loadContext(HttpRequestResponseHolder 
requestResponseHolder) {
        final HttpServletRequest request = requestResponseHolder.getRequest();

        SecurityContext context = 
readSecurityContextFromFlexClientManager(request);
        if(context == null) {
            context = super.loadContext(requestResponseHolder);
        } else {
            final HttpServletResponse response = 
requestResponseHolder.getResponse();
            final HttpSession httpSession = request.getSession(false);
            requestResponseHolder.setResponse(new 
SaveToSessionResponseWrapper(response, request,
                    httpSession != null, context));
        }

        return context;
    }

    @Override
    public void saveContext(SecurityContext context, HttpServletRequest 
request, HttpServletResponse response) {
        // Only save the context, if it was not loaded from the flex client.
        if(request.getAttribute(USED_FLEX_CLIENT) != Boolean.TRUE) {
            super.saveContext(context, request, response);
        } else {
            request.removeAttribute(USED_FLEX_CLIENT);
        }
    }

    private SecurityContext 
readSecurityContextFromFlexClientManager(HttpServletRequest request) {
        // Check if the request contains a flexClientId parameter. If this is 
an AMF
        // request, then it doesn't matter that this check will fail, because 
the default
        // mechanisms will deal with it.
        final String flexClientId = 
request.getParameter(FLEX_CLIENT_ID_PARAMETER);

        // If an Id was found, get the flexClient Object associated with that 
Id and
        // extract the security information from it.
        final FlexClientManager flexClientManager = 
messageBroker.getFlexClientManager();
        final FlexClient flexClient = (flexClientId != null) ?
                flexClientManager.getFlexClient(flexClientId) : null;
        if(flexClient != null) {
            final SecurityContext flexClientContext = new SecurityContextImpl();
            flexClientContext.setAuthentication((Authentication) 
flexClient.getUserPrincipal());

            // Keep in mind, that we used the auth-data of the flex-client.
            request.setAttribute(USED_FLEX_CLIENT, Boolean.TRUE);

            return flexClientContext;
        }
        return null;
    }
}

This acts as a bridge for Spring-Security to get the BlazeDS user credentials 
from BlazeDS. I guess this is the missing part you were looking for.

Chris










________________________________
Von: Oleg Konovalov <[email protected]>
Gesendet: Mittwoch, 20. Juli 2016 19:56:25
An: [email protected]
Betreff: Re: User impersonation in Spring Security3 Flex web app

Chris,

I am using Spring3, BlazeDS, Spring-Flex integration,
but not Spring Boot (would like to learn it for some time regardless).
Also your example doesn't seem to include user impersonation (at least not
mentioned in your blog article), or did I miss something?


TIA,
Oleg.


On Tue, Jul 12, 2016 at 7:28 AM, Christofer Dutz <[email protected]>
wrote:

> Hi Oleg,
>
>
> sounds like you should have a look at BlazeDS. This is the perfect match
> for bringing Flex and Spring together. I even recently created a
> spring-boot-adapter for BlazeDS. The cool thing is, that you can simply
> login to the ChannelSet on the FlexClient and this will result in a Spring
> security login on the server side.
>
>
> Spring Boot Example:
>
> https://github.com/chrisdutz/RAPIRO/tree/master/server/application
[https://avatars0.githubusercontent.com/u/651105?v=3&s=400]<https://github.com/chrisdutz/RAPIRO/tree/master/server/application>

chrisdutz/RAPIRO<https://github.com/chrisdutz/RAPIRO/tree/master/server/application>
github.com
RAPIRO Project



>
> <https://github.com/chrisdutz/RAPIRO/tree/master/server/application>
> A blog article I wrote on BlazeDS and Spring Security:
>
>
> https://dev.c-ware.de/confluence/display/PUBLIC/BlazeDS+per-client-authentication+and+Spring-Security
>
>
> Hope that helps.
>
>
> Chris
>
> ________________________________
> Von: Oleg Konovalov <[email protected]>
> Gesendet: Montag, 11. Juli 2016 17:02:15
> An: [email protected]
> Betreff: User impersonation in Spring Security3 Flex web app
>
> Hi,
>
> I am trying to implement user impersonation in Flex4.6 + Spring3.2 web app
> (so Admin can login as a user and see/do what that user does).
>
> I read a bunch of posts on the net, most seem to suggest using
> UserDetailsService, which seems to be difficult to do in our case. Can
> someone suggest a better solution?
>
> Most examples suggest using special url to allow user to impersonate that
> user. Since we use Flex, don't have deep linking in our app yet (but can
> implement it). Any advice on that?
>
> Code samples?
>
>
> TIA,
>
> Oleg.
>



--
Thank you,
Oleg.

Reply via email to