`
j2eefan
  • 浏览: 2604 次
  • 性别: Icon_minigender_1
  • 来自: DC
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

FlexDS 与 Spring Security 的完美结合

阅读更多
最近一直在思考这个问题,网上也查了,资料也读了。放一个我自己写的SpringSecurityLoginCommand以备日后查阅。

package flex.spring;

import java.security.Principal;
import java.util.List;
import javax.servlet.ServletConfig;

import flex.messaging.FlexContext;
import flex.messaging.security.LoginCommand;
import flex.messaging.security.SecurityException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.AuthenticationProvider;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
* Custom implementation of BlazeDS LoginCommand which utilizes
* Spring Security 2.0 framework underneath.
* <p/>
*
* Date: Oct 14, 2008
* Time: 12:33:46 PM
*/
public class SpringSecurityLoginCommand implements LoginCommand {
  protected final Log log = LogFactory.getLog(getClass());

  public static final String AUTHENTICATION_PROVIDER_BEAN_NAME = "authenticationProvider";
  public static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";

  private final AuthenticationProvider provider;
  private final boolean isPerClientAuthentication;

  public SpringSecurityLoginCommand() {
    isPerClientAuthentication = FlexContext.isPerClientAuthentication();

    WebApplicationContext wac = WebApplicationContextUtils
        .getWebApplicationContext(FlexContext.getServletContext());

    provider = (AuthenticationProvider) wac.getBean(AUTHENTICATION_PROVIDER_BEAN_NAME);
    log.info("Spring Security Authentication Provider initialized - " + provider);
  }

  public Principal doAuthentication(String username, Object credentials) {
    SecurityContext securityContext;

    if (isPerClientAuthentication) {
      securityContext = (SecurityContext) FlexContext.getFlexClient()
          .getAttribute(SPRING_SECURITY_CONTEXT_KEY);

    } else {
      securityContext = (SecurityContext) FlexContext.getFlexSession()
          .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
    }

    Authentication principal;

    if (securityContext == null) {
      UsernamePasswordAuthenticationToken token =
          new UsernamePasswordAuthenticationToken(username, credentials);

      try {
        principal = provider.authenticate(token);

        securityContext = new SecurityContextImpl();
        securityContext.setAuthentication(principal);

        if (isPerClientAuthentication) {
          FlexContext.getFlexClient().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext);
        } else {
          FlexContext.getFlexSession().setAttribute(SPRING_SECURITY_CONTEXT_KEY, securityContext);
        }

        if (log.isDebugEnabled()) {
          log.debug("[Login] Security Context was created.");
        }

      } catch (AuthenticationException e) {

        SecurityException se = new SecurityException();
        se.setMessage(SecurityException.SERVER_AUTHENTICATION_CODE);
        se.setRootCause(e);
        throw se;
      }

    } else {

      principal = securityContext.getAuthentication();

      log.info("[" + username + "] was already authenticated previously.");
    }

    SecurityContextHolder.setContext(securityContext);

    return principal;
  }

  public boolean logout(Principal principal) {
    if (isPerClientAuthentication) {
      FlexContext.getFlexClient().removeAttribute(SPRING_SECURITY_CONTEXT_KEY);
    } else {
      FlexContext.getFlexSession().removeAttribute(SPRING_SECURITY_CONTEXT_KEY);
    }

    SecurityContextHolder.getContext().setAuthentication(null);

    if (log.isDebugEnabled()) {
      log.debug("[Logout] Security Context was removed.");
    }

    return true;
  }

  public boolean doAuthorization(Principal principal, List list) {
    // always return TRUE as the authorization is delegated to Spring Security.
    return true;
  }

  public void start(ServletConfig config) {
    // noop
  }

  public void stop() {
    // noop
  }
}

services-config.xml------------------------------

<?xml version="1.0" encoding="ISO-8859-1"?>
<services-config>

    <services>
        <service-include file-path="remoting-config.xml" />
    </services>

    <factories>
        <factory id="spring" class="adobe.flex.sample.SpringFactory" />
    </factories>

    <security>
        <login-command class="flex.spring.SpringSecurityLoginCommand" server="all">
          <per-client-authentication>true</per-client-authentication>
        </login-command>
        <security-constraint id="default">
            <auth-method>Custom</auth-method>
        </security-constraint>
    </security>

    <channels>

        <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
            <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
                      class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>

    <logging>
        <target class="flex.messaging.log.ConsoleTarget" level="Info">
            <properties>
                <prefix>[BlazeDS] </prefix>
                <includeDate>false</includeDate>
                <includeTime>false</includeTime>
                <includeLevel>true</includeLevel>
                <includeCategory>true</includeCategory>
            </properties>
            <filters>
                <pattern>Endpoint.*</pattern>
                <pattern>Service.*</pattern>
                <pattern>Configuration</pattern>
            </filters>
        </target>
    </logging>

    <system>
        <redeploy>
            <enabled>false</enabled>
        </redeploy>
    </system>

</services-config>

remoting-config.xml-----------------------------

<?xml version="1.0" encoding="ISO-8859-1"?>
<service id="remoting-service"
    class="flex.messaging.services.RemotingService">

    <adapters>
        <adapter-definition id="java-object"
           class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
    </adapters>

    <default-channels>
        <channel ref="my-amf"/>
    </default-channels>

    <destination id="roles">
        <properties>
          <factory>spring</factory>
          <source>roles</source>
          <scope>session</scope>
        </properties>
        <security>
            <security-constraint ref="default" />
        </security>
    </destination>

</service>

spring-config.xml------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="authenticationProvider"
        class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
    <property name="userDetailsService">
      <bean class="org.springframework.security.userdetails.memory.InMemoryDaoImpl">
        <property name="userMap">
          <value>
            david=password,ROLE_ADMIN
            alex=password,ROLE_USER
          </value>
        </property>
      </bean>
    </property>
  </bean>

  <bean id="hello" class="flex.spring.SecurityRoles" />

</beans>

java ------------------------
package flex.spring;

import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContextHolder;

public class SecurityRoles {

  public String allowedAuthorities() {
    Authentication principal = SecurityContextHolder.getContext().getAuthentication();
    StringBuilder result = new StringBuilder();
    for (GrantedAuthority ga : principal.getAuthorities()) {
      result.append(",").append(ga.getAuthority());
    }
    return result.substring(1);
  }
}

Flex Client---------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="100%" height="100%"
creationComplete="init()">

  <mx:Script>
  <![CDATA[
  import mx.controls.Alert;
import mx.messaging.config.ServerConfig;
import mx.rpc.AsyncToken;
import mx.rpc.AsyncResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.messaging.ChannelSet;

// Define a ChannelSet object.
      public var cs:ChannelSet;

      // Define an AsyncToken object.
      public var token:AsyncToken;

      // Initialize ChannelSet object based on the
      // destination of the RemoteObject component.
      private function init():void {
        if (cs == null)
          cs = ServerConfig.getChannelSet(remoteObject.destination);
      }

// Login and handle authentication success or failure.
private function ROLogin():void {
  // Make sure that the user is not already logged in.
        if (cs.authenticated == false) {
          token = cs.login("alex", "password");
    // Add result and fault handlers.
    token.addResponder(new AsyncResponder(LoginResultEvent, LoginFaultEvent));
  }
}

      // Handle successful login.
      private function LoginResultEvent(event:ResultEvent, token:Object=null):void {
        switch(event.result) {
          case "success":
            authenticatedCB.selected = true;
          default:
        }
      }

      // Handle login failure.
      private function LoginFaultEvent(event:FaultEvent, token:Object=null):void {
        switch(event.fault.faultCode) {
          case "Client.Authentication":
          default:
            authenticatedCB.selected = false;
        }
      }

      // Logout and handle success or failure.
      private function ROLogout():void {
        // Add result and fault handlers.
        token = cs.logout();
        token.addResponder(new AsyncResponder(LogoutResultEvent,LogoutFaultEvent));
      }

      // Handle successful logout.
      private function LogoutResultEvent(event:ResultEvent, token:Object=null):void {
        switch (event.result) {
          case "success":
            authenticatedCB.selected = false;
          default:
        }
      }

      // Handle logout failure.
      private function LogoutFaultEvent(event:FaultEvent, token:Object=null):void {
        Alert.show("Logout failure: " + event.fault.faultString);
      }

      // Handle message recevied by RemoteObject component.
      private function resultHandler(event:ResultEvent):void {
        ta.text += "Congratulations! You've got server response: "+ event.result + "\n";
      }

      // Handle fault from RemoteObject component.
      private function faultHandler(event:FaultEvent):void {
        ta.text += "Oops! Something wrong: " + event.fault + "\n";
      }
  ]]>
  </mx:Script>

  <mx:HBox height="45">
    <mx:Button label="Login" click="ROLogin()"/>
    <mx:Button label="What roles do I have?" enabled="{authenticatedCB.selected}"
               click="remoteObject.allowedAuthorities()"/>
    <mx:Button label="Logout" click="ROLogout()"/>
    <mx:CheckBox id="authenticatedCB" label="Authenticated?" enabled="true"/>
  </mx:HBox>

  <mx:TextArea id="ta" width="100%" height="511"/>
  <mx:RemoteObject id="remoteObject"
   destination="hello"
   result="resultHandler(event)"
   fault="faultHandler(event)"/>

</mx:Application>

The end-----------------------------------
分享到:
评论
1 楼 raymond2006k 2009-02-26  
很好很详细,对我挺有帮助。

建议前面加个代码文件列表,思路概要,代码部分使用codestyle方便阅读。

相关推荐

    Spring Security in Action

    Spring Security 实践指南 Spring Security 是一个基于 Java 的安全框架,旨在提供身份验证、授权和访问控制等功能。下面是 Spring Security 的主要知识点: 一、身份验证(Authentication) 身份验证是指对用户...

    Spring Security 资料合集

    - Spring Security 无缝集成于Spring MVC框架,可以方便地与Spring MVC的其他特性配合使用,如异常处理和模型映射。 10. **Spring Boot集成**: - 在Spring Boot项目中,Spring Security 可以通过自动配置快速...

    SpringSecurity.pdf

    在使用Spring Security时,开发者需要熟悉它的相关Maven依赖,这些依赖是Spring Security框架与应用程序集成的基础。通过配置Maven坐标,开发者可以在项目中引入Spring Security,从而开始安全功能的配置与开发。...

    Spring Cloud Gateway 整合 Spring Security 统一登录认证鉴权

    总的来说,将Spring Cloud Gateway与Spring Security相结合,可以构建出一套高效、安全的微服务认证系统,提高整体系统的稳定性和用户体验。这种整合不仅简化了微服务之间的交互,还增强了系统的安全性,是现代...

    springsecurity学习笔记

    - 学习如何集成Spring Security与OAuth2,为API提供授权服务。 - 了解如何使用JWT进行状态管理,包括生成和验证JWT。 - 遇到问题时的调试技巧,如日志配置和安全相关的异常处理。 以上只是Spring Security学习过程...

    SpringSecurity笔记,编程不良人笔记

    在本笔记中,我们将深入探讨SpringSecurity的核心概念、配置以及如何与SpringBoot结合使用。 1. **SpringSecurity核心概念** - **Filter Chain**: SpringSecurity通过一系列过滤器实现其安全功能,这些过滤器构成...

    spring security 完整项目实例

    Spring Security 是一个强大的安全框架,用于为Java应用提供身份验证和授权服务。在这个完整的项目实例中,我们将深入探讨Spring Security的核心概念以及如何将其应用于实际的Web应用程序开发。 首先,我们从用户、...

    spring security3 中文版本

    ### Spring Security 3.0.1 中文版知识点解析 #### 一、Spring Security 3.0.1 概览 ##### 1.1 Spring Security 是什么? Spring Security 是一个强大的、高度可定制的身份验证和访问控制框架。它提供了许多功能...

    SpringSecurity学习总结源代码

    SpringSecurity是Java开发中用于构建安全Web应用的框架,它提供了强大的身份验证、授权和访问控制功能。在本文中,我们将深入探讨SpringSecurity的核心概念、关键组件以及如何配置和使用这个框架。 首先,Spring...

    spring spring security2.5 jar

    1. **依赖管理**:确保Spring Security的jar包与Spring Framework的版本兼容。在项目中正确引入这些jar包,通常通过Maven或Gradle的依赖管理来实现。 2. **配置文件**:在Spring的XML配置文件中,需要添加Spring ...

    spring security 官方文档

    10. **与其他Spring框架的集成**:Spring Security与Spring Boot、Spring MVC、Spring Data等其他Spring组件无缝集成,使得构建安全应用变得更加简单。 在Spring Security的官方文档中,包含了详细的配置指南、API...

    最详细Spring Security学习资料(源码)

    Spring Security是一个功能强大且高度可定制的身份验证和授权框架,专门用于保护Java应用程序的安全性。它构建在Spring Framework基础之上,提供了全面的安全解决方案,包括身份验证、授权、攻击防护等功能。 Spring...

    spring security 4.0.0所需jar包

    例如,`spring-security-core`负责基本的认证和授权逻辑,`spring-security-web`处理与Web安全相关的请求过滤,而`spring-security-config`则简化了在Spring应用上下文中定义安全规则的过程。 使用时,开发者可以...

    SpringBoot+SpringSecurity+WebSocket

    总结来说,这个项目演示了如何在SpringBoot环境中,利用SpringSecurity保证安全性,结合WebSocket实现高效、实时的双向通信。这样的架构对于需要实时交互的Web应用,如在线聊天、实时股票交易、游戏等场景非常适用。...

    SpringBoot+SpringSecurity处理Ajax登录请求问题(推荐)

    SpringBoot+SpringSecurity处理Ajax登录请求问题 SpringBoot+SpringSecurity处理Ajax登录请求问题是SpringBoot开发中的一個常见问题,本文将详细介绍如何使用SpringBoot+SpringSecurity处理Ajax登录请求问题。 ...

    Spring security认证授权

    在这个例子中,我们将深入探讨如何使用Spring Security进行认证和授权,并结合数据库操作进行动态配置。 首先,Spring Security的核心概念包括认证(Authentication)和授权(Authorization)。认证是确认用户身份...

    spring-security 官方文档 中文版

    #### 二、Spring Security 配置与使用 **2.1 Security 命名空间配置** - **命名空间的设计**:Spring Security 提供了一个专用的 XML 命名空间来简化安全性配置。 - **开始使用安全命名空间配置**: - **配置 web...

    精彩:Spring Security 演讲PPT

    ### Spring Security 概述与应用实践 #### 一、引言 在当今互联网时代,网络安全问题日益凸显,尤其是Web应用程序的...同时,结合实际案例的学习,能够帮助我们更好地理解和掌握Spring Security的核心概念与使用技巧。

    spring_security_3.1

    7. **集成Spring MVC**:Spring Security 3.1与Spring MVC无缝集成,可以方便地保护Web控制器和视图。通过注解,如`@Secured`和`@PreAuthorize`,可以在方法级别声明安全约束。 8. **自定义逻辑**:Spring Security...

    springboot springsecurity动态权限控制

    综上所述,通过Spring Boot和Spring Security的结合,我们可以构建一个具备动态权限控制的系统,使菜单权限的管理更加灵活,适应业务的变化。这个过程中,数据库起到了至关重要的作用,存储和管理了所有关于用户、...

Global site tag (gtag.js) - Google Analytics