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.