zoukankan      html  css  js  c++  java
  • Springboot之security框架 登录安全验证授权流程

    一、只进行用户验证,不验证密码(UserDetailsService)

      1、导入security依赖(在前端html页面进行一些判断  需导入xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4")

     1 <dependency>
     2     <groupId>org.springframework.boot</groupId>
     3     <artifactId>spring-boot-starter-security</artifactId>
     4 </dependency>
     5 
     6 <dependency>
     7     <groupId>org.thymeleaf.extras</groupId>
     8     <artifactId>thymeleaf-extras-springsecurity5</artifactId>
     9     <version>3.0.4.RELEASE</version>
    10 </dependency>

      2、配置安全认证类

     1 import org.springframework.beans.factory.annotation.Autowired;
     2 import org.springframework.context.annotation.Bean;
     3 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
     4 import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
     5 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
     6 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
     7 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
     8 import org.springframework.security.core.userdetails.UserDetailsService;
     9 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    10 import org.springframework.security.crypto.password.PasswordEncoder;
    11 import top.xiaoyl.service.CustomUserDetailService;
    12 
    13 @EnableWebSecurity
    14 @EnableGlobalMethodSecurity(prePostEnabled = true)
    15 public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    16 
    17     @Override
    18     protected void configure(HttpSecurity http) throws Exception {
    19         //super.configure(http);
    20         //定制请求的授权规则
    21         http.authorizeRequests().antMatchers("/admin/**","/js/**","/css/**","/images/*","/fonts/**","/**/*.png","/**/*.jpg").permitAll()
    22                 .antMatchers("/","/index.html").permitAll()
    23                .antMatchers("/report").hasRole("USER")
    24                 .and()
    25                 .csrf().ignoringAntMatchers("/druid/*");
    26 
    27 
    28         /*
    29          *  开启自动配置的登陆功能,效果,如果没有登陆,没有权限就会来到登陆页面
    30          *      1、login来到登陆页
    31          *      2、重定向到/login?error表示登陆失败
    32          *      3、更多详细规定
    33          *      4、默认post形式的 /login代表处理登陆
    34          *      5、一但定制loginPage;那么 loginPage的post请求就是登陆
    35          */
    36         http.formLogin().usernameParameter("username").passwordParameter("password")
    37                 .loginPage("/login");
    38 
    39 
    40         /*
    41          *  开启自动配置的注销功能
    42          *      1、访问 /logout 表示用户注销,清空session
    43          *      注销成功会返回 /login?logout 页面;
    44          *      注销成功以后来到首页
    45          */
    46         http.logout().logoutSuccessUrl("/");
    47 
    48 
    49         /*
    50          *  开启记住我功能
    51          *      登陆成功以后,将cookie发给浏览器保存,以后访问页面带上这个cookie,只要通过检查就可以免登录
    52          *      点击注销会删除cookie
    53          */
    54         http.rememberMe().rememberMeParameter("remember");
    57     }
    58 
    59     @Bean
    60     UserDetailsService customUserDetailService() { // 注册UserDetailsService 的bean
    61         return new CustomUserDetailService();
    62     }
    63 
    64     /**
    65      * 认证信息管理
    66      * spring5中摒弃了原有的密码存储格式,官方把spring security的密码存储格式改了
    67      *
    68      */
    69     @Autowired
    70     public void configure(AuthenticationManagerBuilder auth) throws Exception {
    71         auth.userDetailsService(customUserDetailService()) //认证信息存储(自定义)
    72                 .passwordEncoder(passwordEncoder());
    73 //
    74 //        auth.inMemoryAuthentication() //认证信息存储到内存中
    75 //                .passwordEncoder(passwordEncoder())
    76 //                .withUser("user").password(passwordEncoder().encode("123")).roles("USER");
    77 
    78     }
    79 
    80     private PasswordEncoder passwordEncoder() {
    81         return new BCryptPasswordEncoder();
    82     }
    83 
    84 }

      3、自定义用户验证类实现UserDetailsService接口,进行授权验证

     1 @Service
     2 public class CustomUserDetailService implements UserDetailsService {
     3 
     4     @Autowired
     5     private UserService userService;
     6 
     7     @Autowired
     8     HttpServletRequest request;
     9 
    10     @Override
    11     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    12         HttpSession session = request.getSession();
    13         User user = userService.getUserByUsername(username);
    14         if(user==null){
    15             session.setAttribute("loginMsg","用户名"+username+"不存在");
    16             throw new UsernameNotFoundException("用户名"+username+"不存在");
    17         }
    18         List<SimpleGrantedAuthority> authorities = new ArrayList<>();
    19         authorities.add(new SimpleGrantedAuthority("USER"));
    20         return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),authorities);
    21     }
    22 }

    二、进行用户密码验证(AbstractUserDetailsAuthenticationProvider)

      第一种方法虽然也能认证授权,但是问题显而易见,没有进行密码验证,主要用户名对了  就给权限  这很危险

      流程跟一基本一样

      1、导入依赖

      2、配置安全认证类,需要报红色的地方修改一下

     1 @Bean
     2     AbstractUserDetailsAuthenticationProvider customAuthenticationProvide() { // 注册AbstractUserDetailsAuthenticationProvider的bean
     3         return new CustomAuthenticationProvider();
     4     }
     5  
     6 @Autowired
     7     public void configure(AuthenticationManagerBuilder auth) throws Exception {
     8         auth.authenticationProvider(customAuthenticationProvide()); //认证信息存储(自定义)
     9 //
    10 //        auth.inMemoryAuthentication() //认证信息存储到内存中
    11 //                .passwordEncoder(passwordEncoder())
    12 //                .withUser("user").password(passwordEncoder().encode("123")).roles("USER");
    13 
    14     }

      3、自定义用户验证类实现AbstractUserDetailsAuthenticationProvider类,进行授权验证

     1 import org.springframework.beans.factory.annotation.Autowired;
     2 import org.springframework.security.authentication.BadCredentialsException;
     3 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
     4 import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
     5 import org.springframework.security.core.AuthenticationException;
     6 import org.springframework.security.core.authority.SimpleGrantedAuthority;
     7 import org.springframework.security.core.userdetails.UserDetails;
     8 import org.springframework.security.core.userdetails.UsernameNotFoundException;
     9 import org.springframework.stereotype.Service;
    10 import top.xiaoyl.entities.User;
    11 
    12 import javax.servlet.http.HttpServletRequest;
    13 import javax.servlet.http.HttpSession;
    14 import java.util.ArrayList;
    15 import java.util.List;
    16 
    17 @Service
    18 public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
    19 
    20     @Autowired
    21     private UserService userService;
    22 
    23     @Autowired
    24     private HttpServletRequest request;
    25 
    26     @Override
    27     protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
    28 
    29     }
    30 
    31     @Override
    32     protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
    33         System.out.println("retrieveUser");
    34         HttpSession session = request.getSession();
    35         if(username==null || username.length()==0){
    36             session.setAttribute("loginMsg","用户名不能为空");
    37             throw new UsernameNotFoundException("用户名不能为空");
    38         }
    39         User user = userService.getUserByUsername(username);
    40         if(user==null){
    41             session.setAttribute("loginMsg","用户名"+username+"不存在");
    42             throw new UsernameNotFoundException("用户名"+username+"不存在");
    43         }
    44         if(!authentication.getCredentials().toString().equals(user.getPassword())){
    45             session.setAttribute("loginMsg","密码不正确");
    46             throw new BadCredentialsException("密码不正确");
    47         }
    48         List<SimpleGrantedAuthority> authorities = new ArrayList<>();
    49         authorities.add(new SimpleGrantedAuthority("USER"));
    50         return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),authorities);
    51     }
    52 }
  • 相关阅读:
    ajax理论
    模块
    node.js(1)
    ES6
    data对象
    数组
    对象
    webdriver对应的驱动版本
    TrineaAndroidCommon API Guide
    PV,UV,IP概念
  • 原文地址:https://www.cnblogs.com/lxy-java/p/13057449.html
Copyright © 2011-2022 走看看