SPRING SECURITY JAVA配置:Web Security

前一篇,我已经介绍了Spring Security Java配置,也归纳的介绍了一下这个项目方方面面。在这篇文章中,咱们来看一看一个简单的基于web security配置的例子。以后咱们再来做更多的我的定制。php

Hello Web Security

在这个部分,咱们对一个基于web的security做一些基本的配置。能够分红四个部分:html

WebSecurityConfigurerAdapter

@EnableWebSecurity注解以及WebSecurityConfigurerAdapter一块儿配合提供基于web的security。继承了WebSecurityConfigurerAdapter以后,再加上几行代码,咱们就能实现如下的功能:java

  • 要求用户在进入你的应用的任何URL以前都进行验证
  • 建立一个用户名是“user”,密码是“password”,角色是“ROLE_USER”的用户
  • 启用HTTP Basic和基于表单的验证
  • Spring Security将会自动生成一个登录页面和登出成功页面
1
2
3
4
5
6
7
8
9
10
@Configuration
@EnableWebSecurity
public class HelloWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
 
@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) {
auth.inMemoryAuthentication()
.withUser( "user" ).password( "password" ).roles( "USER" );
}
}

做为参考,咱们在这里也给出类似的XML配置,不过有几个特殊配置:git

  • Spring Security会生成一个登录页面,验证失败页面和登出成功页面
  • login-processing-url仅仅处理HTTP POST
  • login-page仅仅经过HTTP GET进入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
< http use-expressions = "true" >
   < intercept-url pattern = "/**" access = "authenticated" />
   < logout
     logout-success-url = "/login?logout"
     logout-url = "/logout"
   />
   < form-login
     authentication-failure-url = "/login?error"
     login-page = "/login"
     login-processing-url = "/login"
     password-parameter = "password"
     username-parameter = "username"
   />
</ http >
< authentication-manager >
   < authentication-provider >
     < user-service >
       < user name = "user"
           password = "password"
           authorities = "ROLE_USER" />
     </ user-service >
   </ authentication-provider >
</ authentication-manager >

AbstractAnnotationConfigDispatcherServletInitializergithub

下一步就是保证ApplicationContext包含咱们刚刚定义的HelloWebSecurityConfiguration。有几种方法均可行,咱们这里使用Spring的AbstractAnnotationConfigDispatcherServletInitializerweb

1
2
3
4
5
6
7
8
9
public class SpringWebMvcInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
 
@Override
protected Class[] getRootConfigClasses() {
return new Class[] { HelloWebSecurityConfiguration. class };
}
...
}

Spring Security一般在web.xml中包含下面几行代码进行初始化:spring

1
2
3
4
5
6
7
8
9
10
11
12
<!-- Creates the Spring Container shared by all Servlets and Filters -->
< listener >
   < listener-class >
     org.springframework.web.context.ContextLoaderListener
   </ listener-class >
</ listener >
 
<!-- Load all Spring XML configuration including our security.xml file -->
< context-param >
   < param-name >contextConfigLocation</ param-name >
   < param-value >/WEB-INF/spring/*.xml</ param-value >
</ context-param >

AbstractSecurity WebApplicationInitializer

最后一步,咱们须要对springSecurityFilterChain定义映射路径。咱们很容易经过继承AbstractSecurityWebApplicationInitializer实现,并能够有选择的经过覆盖方法来定制映射。express

下面是最基本的配置,它能够接受默认的映射路径,springSecurityFilterChain具备如下的特性:api

  • springSecurityFilterChain映射到了”/*”
  • springSecurityFilterChain使用ERROR和REQUEST分派类型(dispatch type)
  • springSecurityFilterChain插入到其它已经配置的servlet过滤器映射(servlet Filter mapping)以前
1
2
3
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}

上面的代码等同于将这几行代码放在web.xml中:安全

1
2
3
4
5
6
7
8
9
10
11
12
13
< filter >
   < filter-name >springSecurityFilterChain</ filter-name >
   < filter-class >
     org.springframework.web.filter.DelegatingFilterProxy
   </ filter-class >
</ filter >
 
< filter-mapping >
   < filter-name >springSecurityFilterChain</ filter-name >
   < url-pattern >/*</ url-pattern >
   < dispatcher >ERROR</ dispatcher >
   < dispatcher >REQUEST</ dispatcher >
</ filter-mapping >

WebApplicationInitializer的次序
在AbstractSecurityWebApplicationInitializer启动以后再加入的servlet过滤器映射,它们有可能会加在springSecurityFilterChain以前。除非这个应用不须要安全验证,不然springSecurityFilterChain须要放在其它全部的过滤器映射以前。@Order能够保证任何WebApplicationInitializer都使用特定的顺序加载。

CustomWebSecurityConfigurerAdapter

这个HelloWebSecurityConfiguration范例,为咱们很好的展现了Spring Security Java配置是如何工做的。让咱们来看看更多定制的配置吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@EnableWebSecurity
@Configuration
public class CustomWebSecurityConfigurerAdapter extends
WebSecurityConfigurerAdapter {
@Override
protected void registerAuthentication(AuthenticationManagerBuilder auth) {
auth
.inMemoryAuthentication()
.withUser( "user" ) // #1
.password( "password" )
.roles( "USER" )
.and()
.withUser( "admin" ) // #2
.password( "password" )
.roles( "ADMIN" , "USER" );
}
 
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers( "/resources/**" ); // #3
}
 
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeUrls()
.antMatchers( "/signup" , "/about" ).permitAll() // #4
.antMatchers( "/admin/**" ).hasRole( "ADMIN" ) // #6
.anyRequest().authenticated() // #7
.and()
.formLogin() // #8
.loginUrl( "/login" ) // #9
.permitAll(); // #5
}
}

咱们也须要更新AbstractAnnotationConfigDispatcherServletInitializer,这样CustomWebSecurityConfigurerAdapter能够实现如下功能:

  • #1 能够在内存中的验证(memory authentication)叫做”user”的用户
  • #2 能够在内存中的验证(memory authentication)叫做”admin”的管理员用户
  • #3 忽略任何以”/resources/”开头的请求,这和在XML配置http@security=none的效果同样
  • #4 任何人(包括没有通过验证的)均可以访问”/signup”和”/about”
  • #5 任何人(包括没有通过验证的)均可以访问”/login”和”/login?error”。permitAll()是指用户能够访问formLogin()相关的任何URL。
  • #6 “/admin/”开头的URL必需要是管理员用户,譬如”admin”用户
  • #7 全部其余的URL都须要用户进行验证
  • #8 使用Java配置默认值设置了基于表单的验证。使用POST提交到”/login”时,须要用”username”和”password”进行验证。
  • #9 注明了登录页面,意味着用GET访问”/login”时,显示登录页面

下面的XML配置和上面的Java配置相似:

Java配置和XML命名空间的相同之处

在看过了更复杂的例子以后,你可能已经找到了一些XML命名空间和Java配置的类似之处。我在这里说明几条有用的信息:

  • HttpSecurity和http命名空间相似。它能够对于某一部分请求进行特别配置。要看个完整的配置实例,详见SampleMultiHttpSecurityConfig
  • WebSecurity和Security的命名空间的元素很相似,后者是针对web的,不须要父节点(security=none, debug等等)。能够对整个web security进行配置。
  • WebSecurityConfigurerAdapter方便咱们定制WebSecurity和HttpSecurity。咱们能够对WebSecurityConfigurerAdapter进行屡次继承,以实现不一样的http行为。详细的实例参见SampleMultiHttpSecurityConfig
  • 咱们以上的Java配置代码做了代码格式化,因此易于阅读。“and()”相似于XML中结束一个元素的结束符。

Java配置和XML命名空间的不一样之处

你已经意识到了XML和Java配置的不一样之处

  • 当你在”#1″和“#2”中建立用户的时候,咱们并无设置为”ROLE_前缀,而咱们在XML设置成了“ROLE_USER”。由于这是个管理,”roles()”方法会自动添加”ROLE_“。若是你不想要”ROLE_“,你可使用”authoritites()”方法。
  • Java配置有一些不一样的默认URL和参数。当要建立自定义的登录页面的时候要将这一条牢记在心。默认的URL使咱们的URL更加RESTful。另外,使用Spring Security能够帮我避免信息泄露)。例如:
    • GET访问/login登录页面,而不是访问/spring_security_login
    • POST访问/login,而不是/j_spring_security_check
    • 用户名默认为parameter,而不是j_username
    • 密码默认是password,而不是j_password
  • Java配置能够更容易将多个请求映射到一样的角色上。#4就将两个URL做了映射,以便全部人均可以访问
  • Java移除了多余的代码。例如,在XML中咱们不得不在form-loginintercept-url中重复两次”/login”,而在Java配置中,咱们靠#5就轻易作到了让用户都能访问到和formLogin()相关的URL。
  • #6映射HTTP请求的时候,咱们使用了“hasRole()”方法,咱们也没有添加”ROLE_”前缀,而在XML中咱们则添加了。这也是咱们应该知道的惯例:”hasRole()”会自动添加”ROLE_”前缀。若是你不想要“ROLE_”前缀,你可使用”access()”方法。

更多的示例

咱们还提供了更多的示例,你应该想跃跃欲试了吧:

从XML命名空间到Java配置

若是你以为从XML转变成Java配置有必定困难,你能够先看看这些测试。这些测试中,XML元素的名称以”Namespace”开头,中间是XML元素的名称,而后以”Tests”结尾。例如,你想学习如何将http元素转换成Java配置,你能够看看NamespaceHttpTests;你若是想学习如何将remember-me命名空间转换成Java配置,参见NamespaceRememberMeTests

欢迎反馈

若是你发现了bug,或者以为有什么地方值得改进,请你不要犹豫,给咱们留言!咱们但愿听到你的想法,以便在大部分人得到代码以前,咱们便确保代码的正确性。很早的尝试新功能是一种简单有效的回馈社区的方法,这样作的好处就是能帮助你得到你但愿得到的功能。

请到“Java Config”目录下的Spring Security JIRA记录下任何问题。记录了一个JIRA以后,咱们但愿(固然并非必须的)你在pull request中提交你的代码。你能够在贡献者指引中阅读更详细的步骤。若是你有任何不清楚的,请使用Spring Security论坛或者Stack Overflow,并使用”spring-security”标签(我会一直查看这个标签)。若是你针对这个博客有任何意见,也请留言。使用合适的工具对每一个人来讲都会带来便利。

结论

你可能已经对基于web的security的Java配置已经有了必定的认识了。下一篇中,咱们将会带你来看下如何用Java配置来配置基于method的security。

原文连接: Springsource 翻译: ImportNew.com 唐小娟
译文连接: http://www.importnew.com/5641.html
转载请保留原文出处、译者和译文连接。]

相关文章
相关标签/搜索