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

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。

  

public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {
}

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

 

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailServiceImpl userDetailService;
    //对每个请求进行细粒度安全性控制的关键在于重载一下方法
    @Override
    protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()//该方法所返回的对象的方法来配置请求级别的安全细节
                        .antMatchers("/login")
                        .permitAll()//对于登录路径不进行拦截
                        .antMatchers("/show").authenticated()//authenticated()表示允许过的用户访问
                    .and()
                    .formLogin()//配置登录页面
                        .loginPage("/login")//登录页面的访问路径
                        .loginProcessingUrl("/check")//登录页面下表单提交的路径
                        .failureUrl("/login")//登录失败后跳转的路径
                        .defaultSuccessUrl("/show")//登录成功后默认跳转的路径
                    .and()
                    .csrf()//启用防跨站伪请求攻击,默认启用
                    .and()
                        .logout()//用户退出操作
                            .logoutUrl("/logout")//用户退出所访问的路径,需要使用Post方式
                            .permitAll()
                            .logoutSuccessUrl("/login?logout=true")
                    .and()
                        .authorizeRequests()
//                    //定义路径保护的配置方法
//                         .antMatchers(HttpMethod.GET,"/admin")
//                        .authenticated()
                        .antMatchers(HttpMethod.GET,"/message/**","/object/**").hasRole("USER")
                        .anyRequest().permitAll()
                    .and()
                        .rememberMe()//启用记住我功能
                            .tokenValiditySeconds(2419200)
            ;
    }
    //配置Spring Security的Filter链
    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }
    //配置user-detail服务
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService)
            .passwordEncoder(new StandardPasswordEncoder("53cr3t"))//密码加密方式

        ;
//        auth.inMemoryAuthentication() //内置用户
//                .withUser("user").password("user").roles("USER");
    }
}

  需要注意的有几点,如果是用xml配置的springmvc环境下,基于javaConfig和注解配置Spring Security同样适用,只需要确保Spring的上下文能够扫描到上述的两个类即可。

  如果在JSP页面下使用Spring的表单标签,该标签默认会自动添加隐藏的CSRF token标签,即防跨站伪请求攻击,如果没有使用Spring的表单标签,则需要手动添加以下标签,尤其是进行logout登出时表单提交,在Form标签内必须保护以下内容。

  

<input type="hiden"
            name="${_csrf.parameterName}"
            value="${_csrf.token}"}

  下面是登录页面

  

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

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

</sf:form>
</body>
</html>

  登出页面

  

<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
    <title>User Manager</title>
</head>
<body>

  <sf:form id="logoutForm" action="${ctx}/logout" method="post">
<a href="#" onclick="document.getElementById(‘logoutForm‘).submit();">注销</a>
</sf:form>
</body>
</html>

  如果我们想要配置自定义认证和授权服务,则需要实现UserDetailsService

  

public class UserDetailServiceImpl implements UserDetailsService {
    private static Logger logger=Logger.getLogger(UserDetailServiceImpl.class);
    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleService roleService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
       logger.info("===========授权============");

        User user= null;
        List<Role> role=null;
        try {
            user = userService.findUserByUsername(username);
            role=roleService.listRoleByUserId(user.getId());
            logger.info("用户角色为:"+role);
        } catch (BaseException e) {
            e.printStackTrace();
        }
        List<GrantedAuthority> list= new ArrayList<GrantedAuthority>();
        list.add(new SimpleGrantedAuthority("ROLE_"+role));
        org.springframework.security.core.userdetails.User authUser = new
                    org.springframework.security.core.userdetails.User
                    (user.getUsername(),user.getPassword(),list);

            return authUser;
    }
}

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

时间: 2024-08-12 16:37:22

更加优雅地配置Spring Securiy(使用Java配置和注解)的相关文章

Spring使用Hibernate和再加SpringData时配置的差别基于Java配置

只使用Spring+Hibernate 配置DataSource.LocalSessionFactoryBean.HibernateTransactionManager import java.util.Properties; import javax.sql.DataSource; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import

eclipse里面配置spring,提示java.lang.ClassNotFoundException:org.springframework.web.servlet.Dispatcher错误

在eclipse里面创建了一个Dynamic 项目,用到spring,一直提示java.lang.ClassNotFoundException: org.springframework.web.servlet.Dispatcher 错误, 后来又提示java.lang.NoClassDefFoundError: org/springframework/context/ApplicationConte 后来新建了一个项目,然后结构什么的都没有改变就可以正常运行了: 对比了一下,发现可能的原因有以下

Spring中通过java的@Valid注解和@ControllerAdvice实现全局异常处理。

通过java原生的@Valid注解和spring的@ControllerAdvice和@ExceptionHandler实现全局异常处理的方法: controller中加入@Valid注解: @RequestMapping(value="/addCountry", method=RequestMethod.POST) public ResponseResult addCountry(@RequestBody @Valid Country country) { return null;

Spring MVC + Security 4 初体验(Java配置版)

这篇文章同样是使用的Java配置,而非XML配置,如果你对于Java配置的Spring MVC开发还不太熟悉,可以先看我这篇文章. 转自:http://xueliang.org/article/detail/20170302232815082 Authority 创建一个 Authority ,实现自 org.springframework.security.core.GrantedAuthority 类,getAuthority 方法只返回一个表示权限名称的字符串,如 AUTH_USER . 

Spring Ioc 基于Java的容器配置

一.基于Java的容器配置 @Configuration & @Bean 注解: 在Spring的新的Java-Configuration的中间产物是基于类的@Configuration的注解和基于方法的@Bean注解.         @Bean注解是用来指明方法的实例化,配置和初始化一个对象是通过Spring的IoC容器来管理的.对于那些熟悉使用以XML配置Spring的<beans /> 标签,@Bean注解和<bean />标签是起相同作用的.你能和Spring的@

Spring Web MVC框架(八) 配置Spring Web MVC

这一篇文章对应于Spring参考文档 Configuring Spring MVC,讲的是Spring Web MVC各部分的配置方法,包括Java代码配置和XML文件配置以及MVC命名空间的使用方法. 启用MVC Java配置和XML命名空间 默认配置 要启用MVC Java配置(@Controller等各种注解)和XML命名空间,如果使用的是Java配置,在配置类上再添加@EnableWebMvc注解即可. @Configuration @EnableWebMvc public class

Spring_总结_03_装配Bean(二)之Java配置

一.前言 本文承接上一节:Spring_总结_03_装配Bean(一)之自动装配 上一节提到,装配Bean有三种方式,首先推荐自动装配.当自动装配行不通时,就需要采用显示配置的方式了. 显示配置有两种方案:Java 和 XML.当需要显示配置时,首选类型安全并且比XML更强大Java配置. 二.Java配置 实现Java配置只需两步: (1)使用@Configuration声明一个配置类 (2)在配置类中使用@Bean声明一个Bean,同时可通过方法名注入bean. 三.Java配置实例 pac

Spring MVC XML 的配置

JavaEE体系结构包括四层,从上到下分别是应用层.Web层.业务层.持久层.Struts和这篇文章中讲解的SpringMVC是Web层的框架,Spring是业务层的框架,之前文章中讲解的Hibernate和MyBatis是持久层的框架. SpringMVC是一种基于Java,实现了Web MVC(模型 - 视图 - 控制器)设计模式,请求驱动类型的轻量级的开源的Web框架,即用了MVC架构模式的思想,将Web层进行职责解耦.基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发

springmvc基于java配置的实现

该案例的github地址:https://github.com/zhouyanger/demo/tree/master/springmvc-noxml-demo 1.介绍 之前搭建SpringMvc项目要配置一系列的配置文件,比如web.xml,applicationContext.xml,dispatcher.xml.Spring 3.X之后推出了基于JavaConfig方式以及注解的形式的配置.在一定程度上简化了Spring项目的配置.近几年特别火的SpringBoot,大大的简化了创建项目