• springsecurity


    1.定义

    Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

    https://springcloud.cc/spring-security-zhcn.html   中文版参考手册

    2.基本原理:一组过滤器链

    UsernamePasswordAuthenticationFilter:用户认证

    ExceptionTranslation:异常处理

    FilterSecurityInterceptor:最终确认是否能登录的拦截器

    备注:在没有验证的情况下,登录后会到默认的验证页面,默认会拦截所有页面,待验证成功后会转到相应的页面

    3.依赖

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

    4.Api简要说明

    authorizeRequests():请求授权

    formLogin():表单登录(表单登录含两部分一个是认证一个是授权)

    anyRequest():任何请求

    authenticated():身份认证

    httpBasic():httpBasic认证方式

    loginPage():指定登录时的认证页面,这里有一个坑死循环需要注意。

    antMatchers():匹配

    permitAll():不需要身份认证

    5.使用数据库验证登录方式

    @Configuration
    @ComponentScan("springsecurity.demo")
    @MapperScan("springsecurity.demo.Mapper")
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.formLogin()//表单登录
                    .and()
                    .authorizeRequests()//权限认证
                    .anyRequest()//任何请求
                    .authenticated()//需要认证
            ;
        }
    }
    
    @Component
    public class MyUserDetailsService  implements UserDetailsService {
        @Autowired
        UserMapper  userMapper;
    
        @Autowired
        PasswordEncoder passwordEncoder;
    
        @Override
        public UserDetails loadUserByUsername(String username) {
            //查询表
            springsecurity.demo.domain.User userByName = userMapper.getUserByName(username);
            //加密
            String encode = passwordEncoder.encode(userByName.getPassword().toString());//应该是在放入数据库的时候加密,这里直接直接取出
            //将查询的结果放入user中,
            // AuthorityUtils.commaSeparatedStringToAuthorityList("admin")表示角色admin(拥有的权限)
            return   new User(username,encode , AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));//需要采用加密方式否者出现{id}为null
        }
    }
    
    @Configuration
    public class SecurityBeanConfig {
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource  getdaDataSource(){
            return  new DruidDataSource();
        }
        @Bean
        public PasswordEncoder  getPasswordEncoder(){
            return  new BCryptPasswordEncoder();//springsecurity 内置的加密器,建议使用
        }
    }
    
    @RestController
    public class UserController {
        @GetMapping("/hello")
        public String testLogin(){
            return  "helloworld  security";
        }
    }
    

    自定义加密方式

    需要实现PasswordEncoder

    重写方法

    encode:对密码进行加密

    matches(CharSequence var1, String var2):var1原密码,var2传过来的密码

    User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities)

    enabled:是否可用

    accountNonExpired:账户是否过期

    credentialsNonExpired:密码是否过期

    accountNonLocked:是否被冻结

    6.自定义登录页面

    6.1使用默认的自定义方式配置

    @Configuration
    @ComponentScan("springsecurity.demo")
    @MapperScan("springsecurity.demo.Mapper")
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.formLogin()
                    .loginPage("/logintest.html")  //登录页面定义
                    .loginProcessingUrl("/authentication/logintest")//默认处理的是login  post
                    .and()
                    .authorizeRequests()
                    .antMatchers("/logintest.html")
                    .permitAll()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .csrf().disable()//跨站域请求伪造关闭,注意不关闭在Chrome中没反应
            ;
        }
    }
    

     6.2使用自定义配置登录页面

    @Configuration
    @ComponentScan("springsecurity.demo")
    @MapperScan("springsecurity.demo.Mapper")
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        MySecurityProperties mySecurityProperties;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.formLogin()
                    .loginPage("/logintest")
                    .loginProcessingUrl("/authentication/logintest")
                    .and()
                    .authorizeRequests()
                    .antMatchers("/logintest",mySecurityProperties.getLogin())
                    .permitAll()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .csrf().disable()
            ;
        }
    }
    
    @RestController
    public class UserController {
        HttpSessionRequestCache  cache= new  HttpSessionRequestCache();
        DefaultRedirectStrategy defaultRedirectStrategy =  new DefaultRedirectStrategy();//重定向页面
    
        @Autowired
        MySecurityProperties securityProperties;
    
        @GetMapping("/logintest")
        @ResponseStatus(HttpStatus.UNAUTHORIZED)
        public Message  testAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {
            SavedRequest savedRequest = cache.getRequest(request, response);
            if(savedRequest!=null){
                String redirectUrl = savedRequest.getRedirectUrl();//获取请求地址
                if(StringUtils.endsWithIgnoreCase(redirectUrl, ".html")){
                    defaultRedirectStrategy.sendRedirect(request, response, securityProperties.getLogin());
                }
            }
            return  new Message("请先登录");
        }
    }
    
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    @Accessors(chain = true)
    public class Message implements Serializable {
        private   Object  mesaage;
    }
    
    <body>
        <h2  style="color: red">简单的登录页面login</h2>
       <form  action="/authentication/logintest" method="post">
           <table>
               <tr>
                   <td>账号:</td>
                   <td ><input type="text"  name="username"/></td>
               </tr>
               <tr>
                   <td>密码:</td>
                   <td> <input type="password"  name="password"/></td>
               </tr>
               <tr>
                   <td colspan="2" style="text-align: right"><input type="submit" value="提交" /></td>
               </tr>
           </table>
       </form>
    </body>
    </html>
    
    @ConfigurationProperties("spring.security")
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    @Accessors(chain = true)
    @Component
    public class MySecurityProperties {
        private   String  login="/logintest.html";
    }
    

     7.自定义成功登陆的返回值

    @Configuration
    @ComponentScan("springsecurity.demo")
    @MapperScan("springsecurity.demo.Mapper")
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        MySecurityProperties mySecurityProperties;
    
        @Autowired
        MyUserDetails  myUserDetails;
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.formLogin()
                    .loginPage("/logintest")
                    .loginProcessingUrl("/authentication/logintest")
                    .successHandler(myUserDetails)
                    .and()
                    .authorizeRequests()
                    .antMatchers("/logintest",mySecurityProperties.getLogin())
                    .permitAll()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .csrf().disable()
            ;
        }
    }
    
    @Component
    public class MyUserDetails implements AuthenticationSuccessHandler {
    
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(new ObjectMapper().writeValueAsString(authentication));
        }
    }
    

     失败类似

    实现AuthenticationFailureHandler实现onAuthenticationFailure方法

    .failureHandler(AuthenticationFailureHandler  xxx)

    8.图片验证

    
    
    
  • 相关阅读:
    c# 进程间同步实现
    mysql 中文支持
    堆排序算法详解
    CodeSmith 使用
    东软C#编程规范
    红伞各版key 申请和下载
    sql 添加删除字段
    第一个Hibernate 程序终于测试通过了
    C#下载大文件并实现断点续传
    Ms rdlc 打印
  • 原文地址:https://www.cnblogs.com/gg128/p/9954179.html
Copyright © 2020-2023  润新知