zoukankan      html  css  js  c++  java
  • 5. Java Configuration Java配置

    在Spring 3.1中,对 Java Configuration (Java配置)的一般支持被添加到Spring框架中。自Spring Security 3.2以来,就有了Spring Security对Java配置的支持,用户可以轻松配置Spring Security,而无需使用任何XML。

    如果您熟悉第6章“安全命名空间配置”,那么您应该会发现它和安全Java配置支持之间有很多相似之处。

    Spring Security提供了 lots of sample applications (许多示例应用程序),演示了Spring Security Java配置的使用。

    5.1  Web Security Java Configuration(网络安全Java配置)

    第一步是创建我们的Spring安全Java配置。该配置创建了一个名为springSecurityFilterChain的Servlet过滤器,它负责应用程序中的所有安全性(保护应用程序URL、验证提交的用户名和密码、重定向到登录表单等)。您可以在下面找到Spring安全Java配置的最基本的例子:


     

    1、这里真没有配置多少内容,但它确实很有用。您可以找到以下功能的摘要:

    2、在你的应用程序中对每个URL进行验证

    3、为你生成一个登陆表单

    4、允许使用用户名Usernameuser和密码Passwordpassword使用验证表单进行验证。

    5、允许用户登出

    6、CSRF attackCSPF攻击防范

    7、Session FixationSession保护

    8、安全 Header 集成

     HTTP Strict Transport Security对安全要求严格的HTTP传输安全

     X-Content-Type-OptionsX-Content-Type-Options集成

            缓存控制(稍后可以允许你缓存静态资源)

     X-XSS-ProtectionX-XSS-Protection集成

    X-Frame-Options 集成防止点击劫持Clickjacking

    9、和以下 Servlet API 方法集成

    HttpServletRequest#getRemoteUser()

     HttpServletRequest.html#getUserPrincipal()

     HttpServletRequest.html#isUserInRole(java.lang.String)

     HttpServletRequest.html#login(java.lang.String, java.lang.String)

     HttpServletRequest.html#logout()

    5.1.1 AbstractSecurityWebApplicationInitializer(抽象安全网络应用程序初始化器)

    下一步是将springSecurityFilterChain注册到war中。这可以在Servlet 3.0+环境中通过支持Spring的WebApplicationInitializer在Java配置中完成。不足为奇的是,Spring Security提供了一个基类AbstractSecurityWebApplicationInitializer(抽象安全性应用程序初始化器),它将确保为您注册springSecurityFilterChain。我们使用AbstractSecurityWebApplicationInitializer(抽象安全性应用程序初始化器)的方式会有所不同,这取决于我们是否已经在使用Spring,或者Spring安全性是我们的应用程序中唯一的Spring组件。

    第5.1.2节,“AbstractSecurityWebApplicationInitializer without Existing Spring”-如果您还没有使用Spring,请使用这些说明。

    第5.1.3节,“AbstractSecurityWebApplicationInitializer with Spring MVC”-如果您已经在使用Spring,请使用这些说明。

    5.1.2 AbstractSecurityWebApplicationInitializer without Existing Spring(没有现有Spring的抽象安全性应用程序初始化器)

    如果您没有使用Spring或Spring MVC,您将需要将网络安全参数(WebSecurityConfig)传入超类,以确保配置被采用。你可以在下面找到一个例子:


     

    安全性应用程序初始化器(SecurityWebApplicationInitializer)将执行以下操作:

    为应用程序中的每个网址自动注册到springSecurityFilterChain过滤器。

    添加一个加载网络安全配置(WebSecurityConfig)的上下文加载器(ContextLoaderListener)。

    5.1.3 AbstractSecurityWebApplicationInitializer with Spring MVC(有springMVC的抽象安全性应用程序初始化器 )

    如果我们在应用程序的其他地方使用Spring,我们可能已经有了一个加载Spring配置的WebApplicationInitializer(web应用初始化器)。如果我们使用以前的配置,我们会得到一个错误。相反,我们应该在现有的应用上下文(ApplicationContext)中注册Spring Security。例如,如果我们使用的是Spring MVC,我们的SecurityWebApplicationInitializer(安全web应用初始化器)看起来就像下面这样:


     

    这只会为应用程序中的每个网址注册springSecurityFilterChain过滤器。之后,我们将确保WebSecurityConfig(web安全配置)加载到我们现有的应用程序初始化器中。例如,如果我们使用Spring MVC,它将被添加到getRootConfigClasses():


    5.2 HttpSecurity(http安全)

    到目前为止,我们的网络安全配置只包含如何验证用户身份的信息。Spring Security如何知道我们想要要求所有用户都经过身份验证?Spring Security如何知道我们想要支持基于表单的身份验证?原因是WebSecurityConfigurerAdapter(web安全配置适配器)在configure(HttpseSecurity http)方法中提供了一个默认配置,如下所示:


     

    上面的默认配置:

    确保我们应用中的所有请求都需要用户被认证

    允许用户进行基于表单的认证

    允许用户使用HTTP基于验证进行认证

    你可以看到这个配置和下面的XML命名配置相似:


     

    java配置使用and()方法相当于XML标签的关闭。这允许我们继续配置父对象。如果你阅读代码,它也是有意义的。我想配置授权请求,配置表单登录和配置HTTP基本身份验证。

    然而,Java配置有不同的默认URL和参数。创建自定义登录页面时请记住这一点。结果是,我们的网址更加RESTful。此外,我们使用有助于防止信息泄露的Spring Security并不十分明显。例如5.3所示:

    5.3 Java Configuration and Form Login(java配置和表单登录)

    当提示您登录时,您可能想知道登录表单是从哪里来的,因为我们没有提到任何HTML文件或JSP。由于Spring Security的默认配置没有为登录页面明确设置URL,Spring Security会根据已启用的功能自动生成一个,并使用处理提交的登录的URL的标准值、用户登录后将被发送到的默认目标URL等等。

    虽然自动生成的登录页面便于快速启动和运行,但大多数应用程序都希望提供自己的登录页面。为此,我们可以更新我们的配置,如下所示:


     

    1、指定登录页的路径

    2、我们必须允许所有用户访问我们的登录页(例如为验证的用户),这个formLogin().permitAll()方法允许基于表单登录的所有的URL的所有用户的访问。

    下面是我们当前配置的一个用JSPs实现的登录页面示例:

    下面的登录页面代表我们当前的配置。如果某些默认值不能满足我们的需求,我们可以轻松地更新我们的配置。


     

    1、一个POST请求到/login用来验证用户

    2、如果参数有error, 验证尝试失败

    3、如果请求蚕食logout存在则登出

    4、登录名参数必须被命名为username

    5、密码参数必须被命名为password

    6、我们必须阅读第18.4.3节“包含CSRF令牌”(Section 18.4.3, “Include the CSRF Token”)以了解更多信息,请阅读第18章“跨站点请求伪造(CSRF)”(Chapter 18,Cross Site Request Forgery (CSRF))一节的参考资料

    5.4 Authorize Requests(请求授权)

    我们的例子中要求用户进行身份验证并且在我们应用程序的每个URL这样做。我么你可以通过给http.authorizeRequests()添加多个子节点来指定多个定制需求到我们的URL。例如:


     

    1、http.authorizeRequests()方法有多个子节点,每个macher按照他们的声明顺序执行。

    2、我们指定任何用户都可以通过访问的多个URL模式。任何用户都可以访问URL以"/resources/", equals "/signup", 或者 "/about"开头的URL。

    3、以 "/admin/" 开头的URL只能由拥有 "ROLE_ADMIN"角色的用户访问。请注意我们使用 hasRole 方法,没有使用 "ROLE_" 前缀。

    4、任何以"/db/" 开头的URL需要用户同时具有 "ROLE_ADMIN" 和 "ROLE_DBA"。和上面一样我们的 hasRole 方法也没有使用 "ROLE_" 前缀。

    5、尚未匹配的任何URL要求用户进行身份验证。

    5.5 Handling Logouts(登出处理)

    当使用WebSecurityConfigurerAdapter, 注销功能会自动应用。默认是访问URL`/logout`将注销登陆的用户:

    使HTTP Session 无效

    清楚所有已经配置的 RememberMe 认证

    清除SecurityContextHolder

    重定向到 /login?logout


     

    1、提供注销支持,使用WebSecurityConfigurerAdapter会自动被应用。

    2、设置触发注销操作的URL (默认是/logout). 如果CSRF内启用(默认是启用的)的话这个请求的方式被限定为POST。 请查阅相关信息JavaDoc相关信息.

    3、注销之后跳转的URL。默认是/login?logout。具体查看JavaDoc文档.

    4、让你设置定制的 LogoutSuccessHandler。如果指定了这个选项那么logoutSuccessUrl()的设置会被忽略。请查阅JavaDoc文档.

    5、指定是否在注销时让HttpSession无效。 默认设置为true。 在内部配置SecurityContextLogoutHandler,有关更多信息, 请查阅JavaDoc文档.

    6、添加一个LogoutHandler,默认情况下SecurityContextLogoutHandler会被添加为最后一个LogoutHandler。

    7、允许指定在注销成功时将移除的cookie。这是一个显示的添加一个CookieClearingLogoutHandler的快捷方式。

    注销也可以通过XML命名空间进行配置,请参阅Spring Security XML命名空间相关文档获取更多细节logout element

    5.5.1 LogoutHandler(登出处理器)

    通常,LogoutHandle的r实现类能够参与到注销处理中。它们将被调用来执行必要的清理。因此,他们不应该抛出异常。提供了各种实现方式:

    PersistentTokenBasedRememberMeServices(基于持久令牌的记忆服务)

    TokenBasedRememberMeServices(基于令牌的记忆服务)

    CookieClearingLogoutHandler(Cookie清除注销处理程序)

    CsrfLogoutHandler(Csrf注销处理程序)

    SecurityContextLogoutHandler(安全上下文注销处理程序)

    详情请参见第17.4节“记住我的界面和实现”。(Section 17.4, “Remember-Me Interfaces and Implementations”

    除了直接提供LogoutHandler实现,fluent应用编程接口还提供了快捷方式,这些快捷方式在封面下提供了各自的LogoutHandler实现。例如,deleteCookies()允许指定注销成功时要删除的一个或多个cookies的名称。与添加CookieClearingLogoutHandler相比,这是一个快捷方式。

    5.5.2 LogoutSuccessHandler(登出成功处理器)

    LogoutSuccessHandler(登出成功处理器)被LogoutFilter(登出处理器)在成功注销后调用,用来进行重定向或者转发相应的目的地。注意这个接口与LogoutHandler(登出处理器)几乎一样,但是可以抛出异常。

    下面是提供的一些实现:

    SimpleUrlLogoutSuccessHandler(简单URL登出成功处理器)

    HttpStatusReturningLogoutSuccessHandler(http状态返回登出成功处理器)

    和前面提到的一样,你不需要直接指定SimpleUrlLogoutSuccessHandler(简单URL登出成功处理器)。而使用流式API接口通过设置logoutSuccessUrl(登出成功URL)快捷方式进行设置SimpleUrlLogoutSuccessHandler简单URL登出成功处理器)。注销成功 后将重定向到设置的URL地址。默认的地址是 /login?logout。

    在REST API场景中HttpStatusReturningLogoutSuccessHandlerhttp状态返回登出成功处理器)会进行一些有趣的改变。LogoutSuccessHandler(登出成功处理器)允许你设置一个返回给客户端的HTTP状态码(默认返回200)来替换重定向到URL这个动作。

    5.5.3 Further Logout-Related References(进一步登出相关参考)

    Logout Handling(登出处理)

    Testing Logout(登出测试)

    HttpServletRequest.logout()(HTTPServletRequest登出)

    Section 17.4, “Remember-Me Interfaces and Implementations”(Remember-Me接口和实现)

    Logging Outin section CSRF Caveats (登出CSRF说明)

    SectionSingle Logout(CAS protocol)(单点登出)

    Documentation for thelogout elementin the Spring Security XML Namespace section(Spring安全XML命名空间部分中注销元素的文档)

    5.6 Authentication(认证)

    到目前为止,我们只看了最基本的身份验证配置。让我们看几个稍微高级一点的配置身份验证的选项。

    5.6.1 In-Memory Authentication(内存中的身份验证)

    我们已经看到了一个单用户配置到内存验证的示例,下面是配置多个用户的例子:


     

    5.6.2 JDBC Authentication(jdbc认证)

    你可以找一些更新来支持JDBC的验证。下面的例子假设你已经在应用程序中定义好了DataSource, jdbc-javaconfig 示例提供了一个完整的基于JDBC的验证。


     

    5.6.3 LDAP Authentication(LDAP认证)

    你可以找一些更新来支持LDAP的身份验证, ldap-javaconfig 提供了一个完成的使用基于LDAP的身份验证的示例。


     

    上面的例子使用了下面的LDIF和一个嵌入的Apache DS LDAP实例。

    dn: ou=groups,dc=springframework,dc=org

    objectclass: top

    objectclass: organizationalUnit

    ou: groups

    dn: ou=people,dc=springframework,dc=org

    objectclass: top

    objectclass: organizationalUnit

    ou: people

    dn: uid=admin,ou=people,dc=springframework,dc=org

    objectclass: top

    objectclass: person

    objectclass: organizationalPerson

    objectclass: inetOrgPerson

    cn: Rod Johnson

    sn: Johnson

    uid: admin

    userPassword: password

    dn: uid=user,ou=people,dc=springframework,dc=org

    objectclass: top

    objectclass: person

    objectclass: organizationalPerson

    objectclass: inetOrgPerson

    cn: Dianne Emu

    sn: Emu

    uid: user

    userPassword: password

    dn: cn=user,ou=groups,dc=springframework,dc=org

    objectclass: top

    objectclass: groupOfNames

    cn: user

    uniqueMember: uid=admin,ou=people,dc=springframework,dc=org

    uniqueMember: uid=user,ou=people,dc=springframework,dc=org

    dn: cn=admin,ou=groups,dc=springframework,dc=org

    objectclass: top

    objectclass: groupOfNames

    cn: admin

    uniqueMember: uid=admin,ou=people,dc=springframework,dc=org

    5.6.4 AuthenticationProvider(认证提供商)

    您可以通过一个自定义的AuthenticationProvider为bean定义自定义身份验证。 例如, 下面这个例子假设自定义身份验证SpringAuthenticationProvider实现了AuthenticationProvider:

    仅当尚未填充AuthenticationManagerBuilder时,才使用此选项。


     

    5.6.5 UserDetailsService(用户详细信息服务)

    你可以通过一个自定义的UserDetailsService(用户详细信息服务)为bean定义自定义身份验证。 例如,下面这个例子假设自定义身份验证SpringDataUserDetailsService实现了UserDetailsService:

    仅当尚未填充AuthenticationManagerBuilder(身份验证管理器生成器)并且未定义AuthenticationProviderBean(身份验证提供商)时,才使用此选项。


     

    你也可以通过让passwordencoder为bean自定义密码如何编码。 例如,如果你使用BCrypt,你可以添加一个bean定义如下图所示:


    5.6.6 LDAP Authentication(LDAP身份认证)

    5.7 Multiple HttpSecurity(多个HttpSecurity)

    我们可以配置多个http安全实例,就像我们可以有多个< http >块一样。关键是多次扩展WebSecurityConfigurerAdapter。例如,下面是一个为以/api/开头的网址进行不同配置的示例。


     

    配置正常的验证。

    1、创建一个WebSecurityConfigurerAdapter,包含一个@Order注解,用来指定个哪一个WebSecurityConfigurerAdapter更优先。

    2、http.antMatcher指出,这个HttpSecurity只应用到以/api/开头的URL上。

    3、创建另外一个WebSecurityConfigurerAdapter实例。用于不以/api/开头的URL,这个配置的顺序在ApiWebSecurityConfigurationAdapter之后,因为他没有指定@Order值为1(没有指定@Order默认会被放到最后).

    5.8 Method Security(方法安全性)

    从版本2.0开始,Spring Security已经大大改进了对为服务层方法增加安全性的支持。它支持JSR-250注释安全性以及框架的原始@Secured注释。从3.0开始,您还可以使用新的基于表达式(expression-based annotations.)的注释。您可以对单个bean应用安全性,使用intercept-methods元素来修饰bean声明,或者使用AspectJ风格的切入点来保护整个服务层中的多个bean。

    5.8.1 EnableGlobalMethodSecurity(启用全局方法安全性)

    我们可以在任何@Configuration实例上使用@EnableGlobalMethodSecurity注释来启用基于注释的安全性。例如,下面将启用Spring Security的@Secured注释。


     

    向方法(在类或接口上)添加注释会相应地限制对该方法的访问。Spring Security的原生注释支持为该方法定义了一组属性。这些将被传递给AccessDecisionManager(访问决策管理器),以便它做出实际的决策:


     

    使用如下代码启用JSR-250注解的支持


     

    这些都是基于标准的,允许应用简单的基于角色的约束,但不具备Spring Security的原生注释。要使用新的基于表达式的语法,您应该使用


     

    等效的Java代码是


     

    5.8.2 GlobalMethodSecurityConfiguration(全局方法安全性配置)

    有时您可能需要执行比@EnableGlobalMethodSecurity注释允许的操作更复杂的操作。对于这些实例,您可以扩展GlobalMethodsecurityConfiguration(全局方法安全性配置),确保您的子类中存在@EnableGlobalMethodSecurity注释。例如,如果您想提供一个自定义的MethodSecurityExpressionHandler(方法安全表达式处理程序),您可以使用以下配置:


     

    关于可以被重写的方法的更多信息,请参考GlobalMethodSecurityConfiguration(全局方法安全性配置)的java文档。

    5.9 Post Processing Configured Objects(后置处理配置的对象)

    Spring Security的Java配置没有公开它配置的每个对象的每个属性。这简化了大多数用户的配置。毕竟,如果每个属性都公开了,用户可以使用标准的bean配置。

    虽然有充分的理由不直接公开每个属性,但是用户可能仍然需要更高级的配置选项。为了解决这个问题,Spring Security引入了ObjectPostProcessor(后置对象处理器)的概念,它可以用来修改或替换许多由Java配置创建的对象实例。例如,如果您想在FilterSecurityInterceptor(安全过滤拦截器)上配置FilterSecurityPublishauthorizationSuccess(安全过滤发布授权成功)属性,可以使用以下方法:


     

    5.10 Custom DSLs(自定义DSLs)

    您可以在Spring Security中提供自己的定制DSL。例如,你可能有这样的东西:


     

    这实际上是像HttpSecurity.authorizeRequests()这样的方法是来实现的。

    自定义DSL可以这样使用:


     

    代码按以下顺序调用:

    1、调用“配置”的配置方法中的代码

    2、调用了“MyCustomDsl的初始化方法”中的代码

    3、调用了“MyCustomDsl的配置方法”中的代码

    如果需要,您可以使用SpringFactories让WebSecurityConfiguerAdapter默认添加MyCustomDsl。例如,您可以在类路径上创建一个名为META-INF/spring.factories的资源,其内容如下:

    org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = sample.MyCustomDsl

    希望禁用默认值的用户可以明确地这样做。


     
  • 相关阅读:
    ClickOnce發布經驗
    reporting Server組件不全引起的致命錯誤
    異步調用
    Usercontrol Hosted in IE
    MATLAB命令大全(转载)
    一种保护眼睛的好方法
    关于oracle自动编号
    An Algorithm Summary of Programming Collective Intelligence (1)
    An Algorithm Summary of Programming Collective Intelligence (3)
    An Algorithm Summary of Programming Collective Intelligence (4)
  • 原文地址:https://www.cnblogs.com/jrkl/p/13513005.html
Copyright © 2011-2022 走看看