Spring Security的使用 #Web安全#权限认证《Spring实战》第4版笔记 (二)

9.3 拦截请求

对每个请求进行细粒度安全性控制的关键在于重载configure(HttpSecurity) 方法。如下代码中的重载configure,为不同的URL路径有选择性的应用安全性

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.authorizeRequests()
                .antMatchers("/test1").authenticated() //对路径认证
                .antMatchers(HttpMethod.POST,"/test2").authenticated() //对路径的POST请求认证
                .anyRequest().permitAll(); //方通其他路径请求,不需要认证和任何的权限
    }	

除了路径选择,还可以通过authenticated() 和 permitAll() 来定义该如何保护路径。authenticated()要求在执行该请求时,必须已经登录了应用。如果用户没有认证的话,Spring Security的Filter将会捕获该请求,并将用户重定向到应用的登录界面。

其他的用来定义如何保护请求的方法

方法 能够做什么
access(String) 如果给定的SpEL表达式计算结果为true,就允许访问
anonymous() 允许匿名访问
authenticated() 允许认证过的用户访问
denyAll() 无条件拒绝访问
fullyAuthenticated() 如果用户是完整认证的话(不是通过Remember-me功能认证的),就允许访问
hasAnyAuthority(String…) 如果用户具备给定权限的某一个的话,就允许访问
hashAnyRole(String…) 如果用户具备给定角色的某一个的话,就允许访问
hashAuthority(String) 如果用户具备给定权限的话,就允许访问
hasIpAddress(String) 如果请求来自给定IP地址的话,就允许访问
hasRole(String) 如果用户具备给定角色的话,就允许访问
not() 对其他访问方法的结果求反
permitAll() 无条件访问
rememberMe() 如果用户是通过Remember-me功能认证的,就允许访问

可以将任意数量的 antMatchers()、regexMatchers()和anyRequest()连接起来,以满足Web应用安全规则的需要,但是!这些规则会按照给定的顺序发挥作用。所以 要将最为具体的请求路径放在前面,而最不具体的路径(如anyRequest())放在最后面。

9.3.1 SpringEL进行安全保护

SpringEL具有强大的多维度保护机制。它能支持很多SpEL表达式

.antMatchers("/test1").access("hasRole('ROLE_USER')")  //具有ROLE_USER角色才能访问的url
安全表达式 计算结果
authentication 用户的认证对象
denyAll 结果始终为false
hasAnyRole(list of roles) 如果用户被授予了列表中的指定角色,结果为true
hashRole(role) 如果用户被授予了指定的角色,结果为true
hasIpAddress(IP Address) 如果请求来自指定IP的话,结果为true
isAnonymous() 如果当前用户为匿名用户,结果为true
isAuthenticated() 如果当前用户进行了认证,结果为true
ifFullyAuthenticated() 如果当前用户进行了完整的认证的话,结果为true
isRememberMe() 如果当前用户是通过Remember-me自动认证的,结果为true
permitAll 结果始终为true
principal 用户的principal对象
.antMatchers("/test1")
 .access("hashRole('ROLE_USER') and hasIpAddress('192.168.1.1') ") //指定权限且来自指定的IP

9.3.2 强制通道的安全性

借助requiresChannel()方法,能够为各种URL模式声明所要求的通道。

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.authorizeRequests()
                .antMatchers("/test1").hasRole("USER")//对路径认证
                .antMatchers(HttpMethod.POST,"/test2").hasRole("USER") //对路径的POST请求认证
                .anyRequest().permitAll() //方通其他路径请求,不需要认证和任何的权限
        .and()
                .requiresChannel()
                .antMatchers("/test1/test3").requiresSecure(); //需要HTTPS
                //.antMatchers("/").requiresInecure(); 始终通过HTTP传送
    }	

此时,只要是对 /test1/test3 的请求,Spring Security都视为需要安全通道并自动将请求重定向到HTTPS上。

9.3.3 防止跨站请求伪造

跨站请求伪造(CSRF):如果一个站点欺骗用户提交请求到其他服务器,即CSRF攻击。

不去处理的方式:httpSecurity.csfr().disable(); //禁用CSRF防护功能

9.4 认证用户

9.4.1 添加自定义的登录页

9.4.2 启用HTTP Basic认证

HTTP Basic认证(HTTP Basic Authentication)会直接通过HTTP请求本身,对访问应用程序的用户进行认证。在REST客户端向它使用的服务进行认证的场景中,这种方式比较适合。

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http
                .csrf().disable()
                .formLogin()  //启用默认的登录页
                .and()
                .httpBasic().realmName("Spittr")  //启用HTTP Basic认证
            ....
    }

9.4.3 启用Remember-me

只要登陆过一次,应用程序就会记住你,当再次回到应用的时候就不需要登录了,启用方式:在configure()方法传入的HttpSecurity对象上调用rememberMe( )即可。

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http
                .csrf().disable()
                .formLogin()  //启用默认的登录页
                .and()
                .httpBasic().realmName("Spittr")  //启用HTTP Basic认证
                .and()
                .rememberMe()
                   .tokenValiditySeconds(2419200)
                   .key("spitterKey")
            ....
    }

默认情况下,这个功能是通过在cookie中存储一个token完成的,这个token最多两周内有效。但是,在这里,我们制定token最多四周内有效(2419200秒)。存储在cookie中的token包含用户名、密码、过期时间和一个私钥—在写入cookie前都进行了MD5哈希。默认情况下,私钥的名为SpringSecured,可以自己命名使它用于Spittr应用。

9.4.4 退出

退出功能是通过Servlet容器中的Filter实现的(默认情况下),这个Filter会拦截针对"/logout"的请求。因此只要发起对"/logout"的请求,就会被Spring Security的LogoutFilter所处理,用户会退出应用,所有的Remember-me token都会被清除掉。在退出完成后,用户浏览器将会重定向到"/login?logout",从而允许用户进行再次登录。

可以通过在configure()配置,重定向指定页面

@Override
protected void configure(HttpSecurity http) throws Exception{
    http
      .formLogon()
      .and()
      .logout()
         .logoutSuccessUrl("/")  //重定向到"/"
         .logoutUrl("/signout")  //重写默认的LogoutFilter拦截路径
}

9.5 保护视图

发布了7 篇原创文章 · 获赞 7 · 访问量 1847

猜你喜欢

转载自blog.csdn.net/TheJam/article/details/104842433