zoukankan      html  css  js  c++  java
  • 【Spring Security】一、入门

    1.Spring Security简介

      Spring Security的前身是Acegi Security,在被收纳为Spring 子项目后正式更名为 Spring Security。
      Spring Security 可以帮助开发者更便捷的完成  认证 + 授权
      认证:确认某主体在系统中是否合法、可用
      授权:即主体通过认证之后,是否允许执行某项操作的过程。
    

    2.Spring Security项目

    在Springboot中添加以下依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    

    或者引入spring-security-webspring-security-config
    两个核心模块,此时声明最简单的hello路由

    @RestController
    @SpringBootApplication
    public class Demo1Application {
        @GetMapping("/hello")
        public String hello(){
            return "hello";
        }
    
        public static void main(String[] args) {
            SpringApplication.run(Demo1Application.class, args);
        }
    
    }
    

    虽然没有进行任何配置,但是Springboot会自动进行配置,在WebSecurityConfigurerAdapter中配置默认运行状态。
    需要在进行HTTP表单验证之后才能访问URL资源

    启动项目时就会默认在控制台输出密码

    2020-08-12 21:45:34.951  INFO 6948 --- [  restartedMain] .s.s.UserDetailsServiceAutoConfiguration : 
    Using generated security password: da4d7e67-5311-46a0-b03a-4476f4ff157a
    

    application.properties中自定义配置账户与密码

    spring.security.user.name=user
    spring.security.user.password=123
    

    在Spring Security 4.x版本中默认的登录方式是HTTP验证,即用户名、密码在弹窗中完成,但是安全性差、无法携带cookie,
    所以后来的默认配置是 HTTP表单认证。

    3.表单认证

    3.1.默认表单认证

    查看WebSecurityConfigurerAdapter 中的configure方法

    protected void configure(HttpSecurity http) throws Exception {
            this.logger.debug("Using default configure(HttpSecurity). If subclassed this will potentially override subclass configure(HttpSecurity).");
            ((HttpSecurity)((HttpSecurity)((AuthorizedUrl)http.
                authorizeRequests(). 
                anyRequest()).   //所有请求
                authenticated().and()). 
                formLogin().and()). //允许进行表单登录进行身份验证
                httpBasic(); //允许用户使用http基本认证
    }
    

    3.2自定义表单验证

    • 3.2.1 创建配置类 继承WebSecurityConfigurerAdapter类
    • 3.2.2 使用@EnbableWebSecurity注解
    • 3.2.3 重写configure(HttpSecurity http)方法
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
        ((HttpSecurity)((HttpSecurity)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)http.
            authorizeRequests().
    
            anyRequest()).   //所有请求  如果是外置的css 与 js 需要修改 否则静态资源也会被拦截
            authenticated().and()).
            formLogin().loginPage("/myLogin.html").permitAll().//自定义登陆页面  登录页不设限访问
                and()). 
            csrf().disable();//关闭 跨站请求伪造防护功能
            }
    }
    
       <form class="form"  action="myLogin.html" method="post">
    	<input type="text" placeholder="用户名" id="username" name="username" >
    	<input type="password" placeholder="密码" id="password" name="password">
    	<button type="submit">登录</button>
      </form>
    
    • 3.2.4 编写自定义登录页 myLogin.html
      Spring Security 会为 myLogin.html 生成一个POST路由用于接受登录请求

    表单其他配置项

    • loginProcessingUrl 指定登录请求路径例如指定为 /login 则form表单中 action = "login"
    • successHandler 指定登录成功的逻辑
    • failureHandler 指定登陆失败的逻辑

    3.3认识HttpSecurity对象

    HttpSecurity对象其实对应着 Spring Security 命名空间配置方式中的XML文件标签,为特定的HTTP请求配置安全策略。

    HttpSecurity 如果是使用Java默认的传统方式配置会相当复杂,所以被设计成了链式调用
    每个方法执行完之后都会返回一个预期的上下文,便于连续调用。

    HttpSecurity提供了很多方法,分别对应命名空间中的标签,例如
    authorizeRequests-><intercept-url>
    formLogin-><form-login>
    httpBasic-><http-basic>
    除非使用and()方法结束当前标签,上下文才会回到HttpSecurity。

    <?xml version="1.0" encoding="UTF-8"?>
    <bean:beans xmlns="http://www.springframework.org/schema/security"
        xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-4.1.xsd">
    
        <!--
        1、设置放行资源,如登录注册页面,静态资源css、js等等
            security="none" 设置此资源不被拦截.
        -->
        <http pattern="/login.html" security="none"></http>
        <http pattern="/loginerror.html" security="none"></http>
        <http pattern="/css/**" security="none"></http>
        <http pattern="/img/**" security="none"></http>
        <http pattern="/js/**" security="none"></http>
        <http pattern="/plugins/**" security="none"></http>
    
        <http>
            <!-- 2、拦截所有(除放行资源外) -->
            <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
            <!-- 
                3、登录表单设置
                1)login-page:指定登录页面;
                2)login-processing-url:指定登录请求路径;
    
                3)default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面;
                4)always-use-default-target:指定了是否在身份验证通过后总是跳转到; 
                                           default-target-url 属性指定的 URL。
                5)authentication-failure-url:指定了身份验证失败时跳转到的页面;                           
             -->
            <form-login login-page="/login.html" 
                        login-processing-url="/login"
                        always-use-default-target="true" 
                        default-target-url="/admin/index.html"
                        authentication-failure-url="/loginerror.html"
    
                         />
            <!--   4、注销设置
                      1)logout-url:指定注销的url;
                      2)logout-success-url:注销成功后登录返回的页面。
            -->         
            <logout logout-url="/logout" logout-success-url="/login.html"/>          
            <!-- 
                5、跨站请求设置(我们这里关闭)
                   1)csrf disabled="true" 关闭 csrf ,如果不加会出现错误
    
                   2)CSRF(Cross-site request forgery):跨站请求伪造,
                     也被称为“One Click Attack”或者 SessionRiding,
                     通常缩写为 CSRF 或者 XSRF,是一种对网站的恶意利用。
             -->            
            <csrf disabled="true" />
    
            <!-- 6、iframe 框架结构展示 -->
            <headers>
                <frame-options policy="SAMEORIGIN" />
            </headers>
        </http>
         <!-- 
                 认证管理器
                 1)我们这里设置一个默认用户
          -->
        <authentication-manager>
            <authentication-provider>
                <user-service>
                    <user authorities="ROLE_USER" name="admin" password="123456" />
                </user-service>
            </authentication-provider>
        </authentication-manager>
    </bean:beans>
    

    4.认证与授权

    基于Spring Security提供默认的用户可能无法满足系统设计的需求。
    与Shiro相同 Spring Security 也支持:
    首先简单配置url与可以访问的角色

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            ((HttpSecurity)((HttpSecurity)((ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)http.
                    authorizeRequests().
                    antMatchers("/admin/**").hasRole("ADMIN").
                    antMatchers("/user/**").hasRole("USER").
                    anyRequest()).   //所有请求  如果是内置的css 与 js 需要修改 否则静态资源也会被拦截
                    authenticated().
                    and()).
                    formLogin().//自定义登陆页面  登录页不设限访问
                    and()).
                    csrf().disable();//关闭 跨站请求伪造防护功能
        }
    }
    

    1.内存中配置用户、角色信息

    **1.1 使用UserDetailsService 接口 **

    @Bean
        public UserDetailsService userDetailsService(){
            InMemoryUserDetailsManager im = new InMemoryUserDetailsManager();
            im.createUser(User.withUsername("user2").password("user2").roles("USER").build());
            im.createUser(User.withUsername("admin2").password("admin2").roles("ADMIN").build());
            return im;
        }      
    

    **1.2 实现WebSecurityConfigurerAdapter **

    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(AuthenticationManagerBuilder auth)throws Exception  {
            auth.inMemoryAuthentication().
                    withUser("user").password("{noop}user").roles("USER").and().
                    withUser("admin").password("{noop}admin").roles("ADMIN");
        }
    }
    

    2.在数据库中配置用户、角色信息

    2.1使用默认数据库表
    使用JdbcUserDetailsManager,与内存中存储用户UserDetailsService 没有区别。默认使用的数据库模型在
    /org/springframework/security/core/userdetails/jdbc/users.ddl
    2.2使用自定义数据库表
    自定义数据库表需要包含UserDetail中一系列在验证时会用到的信息,自定义实体实现UserDetails接口

    package org.springframework.security.core.userdetails;
    
    import java.io.Serializable;
    import java.util.Collection;
    import org.springframework.security.core.GrantedAuthority;
    
    public interface UserDetails extends Serializable {
        Collection<? extends GrantedAuthority> getAuthorities();
    
        String getPassword();
    
        String getUsername();
    
        boolean isAccountNonExpired();
    
        boolean isAccountNonLocked();
    
        boolean isCredentialsNonExpired();
    
        boolean isEnabled();
    }
    
    

    实现UserDetailsService接口,重写loadUserByUsername方法,使用Dao操作返回 UserDetails 的实现类对象即可

    public interface UserDetailsService {
        UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
    }
    
  • 相关阅读:
    fstab是什么?被谁用?怎么写?
    一个驱动导致的内存泄漏问题的分析过程(meminfo->pmap->slabtop->alloc_calls)
    Ubuntu下doxygen+graphviz使用概录
    记录Ubuntu下使用docker使用
    hidraw设备简要分析
    一个版本烧录过程中记录:fdisk、mkfs.ext4、make_ext4fs、img2simg、simg2img
    bootrom/spl/uboot/linux逐级加载是如何实现的?
    Linux uevent分析、用户接收uevent以及mdev分析
    sched_yield()和nanosleep()对进程调度的影响
    Linux Thermal Framework分析及实施
  • 原文地址:https://www.cnblogs.com/shinyrou/p/13493699.html
Copyright © 2011-2022 走看看