网络科技

    今日:668| 主题:246446
收藏本版
互联网、科技极客的综合动态。

[其他] 更加优雅地配置Spring Securiy(使用Java配置和注解)

[复制链接]
△ 落殇 发表于 2016-10-15 02:00:13
380 14

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Spring Security 借助一系列Servlet Filter 来提供安全性功能,但是借助Spring的小技巧,我们只需要配置一个Filer就可以了,DelegatingFilterProxy是一个特殊的Servlet Filter,它本身所做的工作并不多,只是将工作委托给一个javax.servlet.Filter 的实现类,这个实现类作为一个bean注册再Spring应用的上下文中。
  如果了解过用xml配置spring security的朋友就知道,用基于xml配置Spring Security过程繁琐,而且不容易学习和入门,但是基于javaConfig和注解则大大简化了这一配置,下面我们来看看是如何用java的方式配置Spring Security
  首先我们需要配置DelegatingFilterProxy,我们只需要拓展一个新类,该类实现了WebApplicationInitializer,因此Spring会发现它并用他在Web容器中注册DelegatingFilterProxy。

  1. public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {
  2. }
复制代码
接下来我们需要启用Web安全性功能,也是只需要拓展一个类,Spring Security 必须配置在一个实现了WebSecurityConfigurer 的bean中,或者拓展WebSecurityConfigurerAdapter 。在Spring 应用上下文中,任何实现了    WebSecurityConfigurerAdapter的bean都可以用来配置Spring Security。常用的配置已贴上,也全都写上了对应的注释。  

  1. @Configuration
  2. @EnableWebSecurity
  3. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  4.     @Autowired
  5.     private UserDetailServiceImpl userDetailService;
  6.     //对每个请求进行细粒度安全性控制的关键在于重载一下方法
  7.     @Override
  8.     protected void configure(HttpSecurity http) throws Exception {
  9.             http
  10.                     .authorizeRequests()//该方法所返回的对象的方法来配置请求级别的安全细节
  11.                         .antMatchers("/login")
  12.                         .permitAll()//对于登录路径不进行拦截
  13.                         .antMatchers("/show").authenticated()//authenticated()表示允许过的用户访问
  14.                     .and()
  15.                     .formLogin()//配置登录页面
  16.                         .loginPage("/login")//登录页面的访问路径
  17.                         .loginProcessingUrl("/check")//登录页面下表单提交的路径
  18.                         .failureUrl("/login")//登录失败后跳转的路径
  19.                         .defaultSuccessUrl("/show")//登录成功后默认跳转的路径
  20.                     .and()
  21.                     .csrf()//启用防跨站伪请求攻击,默认启用
  22.                     .and()
  23.                         .logout()//用户退出操作
  24.                             .logoutUrl("/logout")//用户退出所访问的路径,需要使用Post方式
  25.                             .permitAll()
  26.                             .logoutSuccessUrl("/login?logout=true")
  27.                     .and()
  28.                         .authorizeRequests()
  29. //                    //定义路径保护的配置方法
  30. //                         .antMatchers(HttpMethod.GET,"/admin")
  31. //                        .authenticated()
  32.                         .antMatchers(HttpMethod.GET,"/message/**","/object/**").hasRole("USER")
  33.                         .anyRequest().permitAll()
  34.                     .and()
  35.                         .rememberMe()//启用记住我功能
  36.                             .tokenValiditySeconds(2419200)
  37.             ;
  38.     }
  39.     //配置Spring Security的Filter链
  40.     @Override
  41.     public void configure(WebSecurity web) throws Exception {
  42.         super.configure(web);
  43.     }
  44.     //配置user-detail服务
  45.     @Override
  46.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  47.         auth.userDetailsService(userDetailService)
  48.             .passwordEncoder(new StandardPasswordEncoder("53cr3t"))//密码加密方式

  49.         ;
  50. //        auth.inMemoryAuthentication() //内置用户
  51. //                .withUser("user").password("user").roles("USER");
  52.     }
  53. }
复制代码
需要注意的有几点,如果是用xml配置的springmvc环境下,基于javaConfig和注解配置Spring Security同样适用,只需要确保Spring的上下文能够扫描到上述的两个类即可。
  如果在JSP页面下使用Spring的表单标签,该标签默认会自动添加隐藏的CSRF token标签,即防跨站伪请求攻击,如果没有使用Spring的表单标签,则需要手动添加以下标签,    尤其是进行logout登出时表单提交,在Form标签内必须保护以下内容。  

  1. <input type="hiden"
  2.             name="${_csrf.parameterName}"
  3.             value="${_csrf.token}"}
复制代码
下面是登录页面

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
  3. <html>
  4. <head>
  5.     <title>login</title>
  6. </head>
  7. <body>
  8. <sf:form action="check" method="post" commandName="user" >
  9.     用户名:<sf:input path="username"></sf:input>
  10.     password:<sf:password path="password"></sf:password>
  11.     <input id="remember_me" name="remember-me" type="checkbox">
  12.     <label for="remember_me" class="inline">Remember me</label>

  13.     <input type="submit" value="提交" >

  14. </sf:form>
  15. </body>
  16. </html>
复制代码
登出页面

  1. <%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
  2. <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
  3. <html>
  4. <head>
  5.     <title>User Manager</title>
  6. </head>
  7. <body>
  8.    
  9.   <sf:form id="logoutForm" action="${ctx}/logout" method="post">
  10. <a href="#" >注销</a>
  11. </sf:form>
  12. </body>
  13. </html>
复制代码
如果我们想要配置自定义认证和授权服务,则需要实现UserDetailsService

  1. public class UserDetailServiceImpl implements UserDetailsService {
  2.     private static Logger logger=Logger.getLogger(UserDetailServiceImpl.class);
  3.     @Autowired
  4.     private IUserService userService;
  5.     @Autowired
  6.     private IRoleService roleService;
  7.     @Override
  8.     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  9.        logger.info("===========授权============");

  10.         User user= null;
  11.         List<Role> role=null;
  12.         try {
  13.             user = userService.findUserByUsername(username);
  14.             role=roleService.listRoleByUserId(user.getId());
  15.             logger.info("用户角色为:"+role);
  16.         } catch (BaseException e) {
  17.             e.printStackTrace();
  18.         }
  19.         List<GrantedAuthority> list= new ArrayList<GrantedAuthority>();
  20.         list.add(new SimpleGrantedAuthority("ROLE_"+role));
  21.         org.springframework.security.core.userdetails.User authUser = new
  22.                     org.springframework.security.core.userdetails.User
  23.                     (user.getUsername(),user.getPassword(),list);

  24.             return authUser;
  25.     }
  26. }

复制代码
该配置将安全级别细分到角色。重写的方法传来的参数为登录的username,再通过该参数从数据库中获取用户,以及相对应的权限,最终通过 将用户、密码、权限传入并实例化org.springframework.security.core.userdetails.User ,从而授权结束。配置安全路径或者方法中的权限依据上述方法中获取并绑定的权限。至此我们就可以对路径进行安全权限保护了。
友荐云推荐




上一篇:How to transfer your iCloud calendar to Android
下一篇:杭州云栖大会上,阿里云都放了哪些大招?
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

邓林玲 发表于 2016-10-15 10:07:33
看完帖子,洗洗睡了!
回复 支持 反对

使用道具 举报

roosterhpf 发表于 2016-10-15 10:38:18
前排支持下了哦~
回复 支持 反对

使用道具 举报

惟楚有才 发表于 2016-10-18 21:23:01
边撸边过
回复 支持 反对

使用道具 举报

黄丹 发表于 2016-10-18 22:42:27
一粒盐,发了脾气就是海。
回复 支持 反对

使用道具 举报

空心印末夕情 发表于 2016-10-22 11:41:42
网络科技老油条路过
回复 支持 反对

使用道具 举报

儿易 发表于 2016-10-22 11:47:15
就算是一坨屎,也有遇见屎壳郎的那天。所以你大可不必为今天的自己有太多担忧。
回复 支持 反对

使用道具 举报

thisis 发表于 2016-10-22 20:45:03
现在你骂我,是因为你还不了解我,等到以后你了解了我,你一定会动手打我的。
回复 支持 反对

使用道具 举报

答案太多不想抄 发表于 2016-10-25 23:39:57
现在整个人都不好了
回复 支持 反对

使用道具 举报

akanl 发表于 2016-10-26 20:15:22
终于看完了,很不错!
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表