• springboot简单集成Security配置


    集成Security安全框架

    引入依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-securityartifactId>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
        <version>1.2.79version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    编写配置类WebSecurityConfig(自定义资源权限规则处理)

    package com.lzj.config;
    
    import com.lzj.config.security.MyUserDetailsService;
    import com.lzj.handler.auth.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    import org.springframework.web.cors.CorsUtils;
    
    /**
     * 

    * Security配置类 *

    * * @author:雷子杰 * @date:2022/8/6 */
    @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private MyUserDetailsService myUserDetailsService; @Autowired private MyAuthenticationFailureHandler myAuthenticationFailureHandler; @Autowired private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler; @Autowired private LogoutSuccessHandlerImpl logoutSuccessHandler; @Autowired private MyAuthenticationEntryPoint myAuthenticationEntryPoint; @Autowired private MyAccessDeniedHandler myAccessDeniedHandler; @Override public void configure(HttpSecurity http) throws Exception { // 什么是(cors 预检请求) 就是你要跨域请求得时候 你要预先发一个请求看对面是拦你还是放你 //第1步:解决跨域问题。cors 预检请求放行,让Spring security 放行所有preflight request(cors 预检请求) http.formLogin().loginProcessingUrl("/login").permitAll(); http.authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll(); //放行掉这个iframe加载 http.headers().frameOptions().disable(); http.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler); // //禁用csrf // http.csrf().disable(); // sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // .and().headers().cacheControl() //配置权限 http.authorizeRequests() // 放行注册请求 .antMatchers(HttpMethod.POST,"/user/registerUser").permitAll() // 放行swagger .antMatchers("/swagger-ui.html").permitAll() .anyRequest() .access(("@dynamicPermission.checkPermisstion(authentication)")) .and().csrf().disable(); // 自己的过滤器 http.addFilterAt(myUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); //第6步:处理异常情况:认证失败和权限不足 http.exceptionHandling().authenticationEntryPoint(myAuthenticationEntryPoint).accessDeniedHandler(myAccessDeniedHandler); } //自定义filter交给工厂管理 @Bean public MyUsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter() throws Exception { MyUsernamePasswordAuthenticationFilter filter = new MyUsernamePasswordAuthenticationFilter(); filter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler); filter.setAuthenticationFailureHandler(myAuthenticationFailureHandler); filter.setAuthenticationManager(authenticationManagerBean()); return filter; } @Bean public BCryptPasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } //用户密码加密验证 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService( myUserDetailsService).passwordEncoder(passwordEncoder()); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    编写配置自定义拦截器(分离式开发)

    MyAuthenticationSuccessHandler(自定义登陆成功处理)

    package com.lzj.handler.auth;
    
    import com.alibaba.fastjson.JSON;
    import com.lzj.entity.User;
    import com.lzj.entity.UserLogin;
    import com.lzj.enums.ResultInfo;
    import com.lzj.config.security.UserAuth;
    import com.lzj.service.UserLoginService;
    import com.lzj.utils.IpUtil;
    import com.lzj.utils.Result;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.Date;
    
    /**
     * 

    * 自定义登陆成功处理 *

    * * @author:雷子杰 * @date:2022/8/6 */
    @Component public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Reference private UserLoginService userLoginService; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { //验证成功来到这个处理器 //然后获取用户信息 UserAuth user = (UserAuth) authentication.getPrincipal(); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(JSON.toJSONString(Result.ok() .setCode(ResultInfo.VERIFY_SUCCESS.getCode()) .setMessage(ResultInfo.VERIFY_SUCCESS.getMessage()).data("user", user))); //这下面的是非必须的,这是我数据库中用来存储登陆记录的一个表 //更新用户登录ip地址,最新登录时间 String ipAddress = IpUtil.getIp(request); String ipSource = IpUtil.getIpSource(ipAddress); User loginUser = user.getUser(); UserLogin login = new UserLogin(); login.setAvatar(loginUser.getAvatar()); login.setIpAddress(ipAddress); login.setIpSources(ipSource); login.setNickname(loginUser.getNickname()); login.setLoginTime(new Date()); //查询他上次得登录时间设置为上次登录时间 //这个时间应该设置到redis中 每次登录就存入redis作为上次登录时间 并且每次更新 //存入表 userLoginService.save(login); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    MyAuthenticationFailureHandler(自定义登陆失败处理)

    package com.lzj.handler.auth;
    
    import com.alibaba.fastjson.JSON;
    import com.lzj.enums.ResultInfo;
    import com.lzj.utils.Result;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.authentication.AuthenticationFailureHandler;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * 

    * 自定义登陆失败处理 *

    * * @author:雷子杰 * @date:2022/8/6 */
    @Component public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { //来到登录失败处理器 //这个返回可以封装一下 就2个不用了 response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(JSON.toJSONString(Result.error() .setCode(ResultInfo.LOGIN_FAILED.getCode()) .setMessage(ResultInfo.LOGIN_FAILED.getMessage()))); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    LogoutSuccessHandlerImpl(自定义认证注销处理)

    package com.lzj.handler.auth;
    
    import com.alibaba.fastjson.JSON;
    
    import com.lzj.utils.Result;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * 

    * 自定义认证注销处理 *

    * * @author:雷子杰 * @date:2022/8/6 */
    @Component public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler { @Override public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.getWriter().write(JSON.toJSONString(Result.ok().setMessage("注销成功"))); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    自定义登录账号密码处理

    package com.lzj.handler.auth;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.lzj.exception.security.MyAuthenticationException;
    import com.lzj.service.UserService;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.MediaType;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Map;
    
    /**
     * 

    * 自定义登录账号密码处理 *

    * * @author:雷子杰 * @date:2022/8/6 */
    public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Reference private UserService userService; @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { //携带头要是json格式得application/json;charset=UTF-8 //前后端分离 这里是接收的是json串 if (request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE) || request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)){ ObjectMapper objectMapper = new ObjectMapper(); //token对象 UsernamePasswordAuthenticationToken authRequest = null; //取authenticationBean Map<String, String> authenticationBean = null; //用try with resource,方便自动释放资源 //用try with resource,方便自动释放资源 try (InputStream is = request.getInputStream()) { //字符串转集合 authenticationBean = objectMapper.readValue(is, Map.class); } catch (IOException e) { //将异常放到自定义的异常类中 System.out.println(e.getMessage()); throw new MyAuthenticationException(e.getMessage()); } try { if (!authenticationBean.isEmpty()) { //获得账号、密码 String username = authenticationBean.get(SPRING_SECURITY_FORM_USERNAME_KEY); String password = authenticationBean.get(SPRING_SECURITY_FORM_PASSWORD_KEY); //可以验证账号、密码 // System.out.println("username = " + username); // System.out.println("password = " + password); //检测账号、密码是否存在 if (userService.checkLogin(username, password)) { //将账号、密码装入UsernamePasswordAuthenticationToken中 authRequest = new UsernamePasswordAuthenticationToken(username, password); setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } } } catch (AuthenticationException e) { e.printStackTrace(); throw new MyAuthenticationException(e.getMessage()); } throw new MyAuthenticationException("用户或者密码错误"); } return this.attemptAuthentication(request,response); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    UserServiceImpl

    @Component
    @Service
    @Slf4j
    @Transactional
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
        @Autowired
        private UserMapper userMapper;
        @Autowired
        private BCryptPasswordEncoder bCryptPasswordEncoder;
        
        
        /**
         * 检测用户账号密码是否存在
         * @param username 用户名
         * @param password 密码
         * @return 是否存在
         */
        @Override
        public boolean checkLogin(String username, String password) {
            //从用户表里面查出用户 然得到加密的密码
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.select("password").eq("username", username);
    
            User user = userMapper.selectOne(wrapper);
            if(user==null){
                return  false;
            }
            //这个是加密后的密码 在数据库里面
            String userPassword = user.getPassword();
            //用加密匹配这个 能匹配返回true 不能返回false
            return   bCryptPasswordEncoder.matches(password, userPassword);
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    自定义登陆处理

    package com.lzj.handler.auth;
    
    import com.alibaba.fastjson.JSON;
    import com.lzj.utils.Result;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.AuthenticationEntryPoint;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * 

    * 自定义登录处理 *

    * * @author:雷子杰 * @date:2022/8/6 */
    @Component public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint { /** */ @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { response.setContentType("application/json;charset=utf-8"); response.getWriter().write( JSON.toJSONString(Result.error().setMessage("请登录"))); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    自定义权限处理

    package com.lzj.handler.auth;
    
    import com.alibaba.fastjson.JSON;
    import com.lzj.utils.Result;
    import org.springframework.security.access.AccessDeniedException;
    import org.springframework.security.web.access.AccessDeniedHandler;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * 

    * 自定义权限处理 *

    * * @author:雷子杰 * @date:2022/8/6 */
    @Component public class MyAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { response.setContentType("application/json;charset=utf-8"); response.getWriter().write(JSON.toJSONString(Result.error().setMessage("没有权限"))); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    自定义认证数据源

    定义Security里的数据源实体类

    package com.lzj.config.security;
    
    import com.lzj.entity.User;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import java.util.Collection;
    
    /**
     * 

    * Security里的数据源实体类 *

    * * @author:雷子杰 * @date:2022/8/6 */
    public class UserAuth implements UserDetails { @Override public String toString() { return "UserAuth{" + "user=" + user + ", authorities=" + authorities + '}'; } private User user; private Collection<? extends GrantedAuthority> authorities; public UserAuth() { } public UserAuth(User user, Collection<? extends GrantedAuthority> authorities) { this.user = user; this.authorities = authorities; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public void setAuthorities(Collection<? extends GrantedAuthority> authorities) { this.authorities = authorities; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUsername(); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    自定义数据源配置

    package com.lzj.config.security;
    
    import com.lzj.entity.User;
    import com.lzj.service.UserService;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.stereotype.Service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 

    * 自定义数据源配置 *

    * * @author:雷子杰 * @date:2022/8/6 */
    @Service public class MyUserDetailsService implements UserDetailsService { @Reference private UserService userService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { if(username.isEmpty()){ throw new UsernameNotFoundException("用户名为空"); } //根据用户名找user User user = userService.getUserByUsername(username); if(user!=null){ List<GrantedAuthority> authorities=new ArrayList<>(); //根据用户名查找用户角色列表 List<String> roles = userService.listUserRolesByUsername(username); //这样写减少对象指针 好一点 SimpleGrantedAuthority simpleGrantedAuthority=null; for (String role :roles){ simpleGrantedAuthority =new SimpleGrantedAuthority(role); authorities.add(simpleGrantedAuthority); } UserAuth userAuth=new UserAuth(); userAuth.setUser(user); userAuth.setAuthorities(authorities); return userAuth; } else { throw new UsernameNotFoundException("没有该用户"); } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    UserServiceImpl

    @Component
    @Service
    @Slf4j
    @Transactional
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
        @Autowired
        private UserMapper userMapper;
        
        
        /**
         * 通过用户名获取用户信息
         * @param username 用户名
         * @return 查询到的信息
         */
        @Override
        public User getUserByUsername(String username) {
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("username", username);
            User user = userMapper.selectOne(wrapper);
            return user;
        }
        
        /**
         * 根据用户名查找权限信息
         * @param username 用户名
         * @return 权限信息集合
         */
        @Override
        public List<String> listUserRolesByUsername(String username) {
    
            List<String> roles = userMapper.listUserRolesByUsername(username);
            return roles;
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    UserMapper.xml

          
    !--    根据用户名查找该用户的权限-->
        <select id="listUserRolesByUsername" resultType="java.lang.String">
            select tb_role.role_name
            from tb_role, tb_user, tb_role_user
            where tb_role.role_id=tb_role_user.role_id
              and tb_user.user_id=tb_role_user.user_id
              and tb_user.username=#{username}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    自定义异常处理

    MyaccessDeniedException

    package com.lzj.exception.security;
    
    import org.springframework.security.access.AccessDeniedException;
    
    /**
     * 

    * *

    * * @author:雷子杰 * @date:2022/8/6 */
    public class MyaccessDeniedException extends AccessDeniedException { public MyaccessDeniedException(String msg) { super(msg); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    MyAuthenticationException

    package com.lzj.exception.security;
    
    import org.springframework.security.core.AuthenticationException;
    
    /**
     * 

    * *

    * * @author:雷子杰 * @date:2022/8/6 */
    public class MyAuthenticationException extends AuthenticationException { public MyAuthenticationException(String msg) { super(msg); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    权限判断与获取(不一定要添加)

    package com.lzj.config.security;
    
    import com.alibaba.fastjson.JSON;
    import com.lzj.entity.Api;
    import com.lzj.exception.security.MyaccessDeniedException;
    import com.lzj.service.UserService;
    import com.lzj.utils.RedisUtil;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.stereotype.Component;
    import org.springframework.util.AntPathMatcher;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    import java.util.List;
    
    /**
     * 

    * 权限判断与获取 *

    * * @author:雷子杰 * @date:2022/8/6 */
    @Component public class DynamicPermission { private final static String PERMISSION_KEY="PERMISSION_KEY"; @Autowired private RedisUtil redisUtil; @Autowired HttpServletRequest request; @Reference private UserService userService; /** * 判断有访问API的权限 * @param authentication * @return * @throws MyaccessDeniedException */ public boolean checkPermisstion(Authentication authentication) throws MyaccessDeniedException, IOException { String name = authentication.getName(); //如果是匿名用户 给匿名用户get权限 查看 if(name.equals("anonymousUser")){ String method = request.getMethod(); if(method.equals("GET")){ return true; }else{ throw new MyaccessDeniedException("非法操作!"); } } //获取当前用户认证信息 Object principal = authentication.getPrincipal(); if(principal instanceof UserDetails) { UserDetails userDetails = (UserDetails) principal; //获取到用户名登陆时输入表单的用户名 String username = userDetails.getUsername(); //通过账号获取资源鉴权查看当前用户下的权限信息表 //这个鉴权经查询常要用到 可以加入缓存 //免得 List<Api> apiUrls = getApiUrlByUserName(username); //AntPathMatcher antPathMatcher = new AntPathMatcher(); //当前访问路径 String requestURI = request.getRequestURI(); //提交类型 String urlMethod = request.getMethod(); //判断当前路径在不在访问资源中 boolean hashAntPath=false; int hasMethod=-1; AntPathMatcher pathMatcher = new AntPathMatcher(); //判断当前访问路径在不在权限表里面 for(Api item :apiUrls){ if(pathMatcher.match(item.getUrl(), requestURI)){ hashAntPath=true; } hasMethod=item.getMethod().toUpperCase().indexOf(urlMethod.toUpperCase()); if(hashAntPath && hasMethod!=-1){ break; } } boolean res=hashAntPath && hasMethod!=-1; if(res){ return res; } else { throw new MyaccessDeniedException("用户权限不足!"); } } else{ throw new MyaccessDeniedException("不是UserDetails类型!"); } } private List<Api> getApiUrlByUserName(String username) { List<Api> urlApis=null; String key= PERMISSION_KEY+"_"+username; String api = (String) redisUtil.get(key); //String api = (String) redisTemplate.opsForValue().get(key); if(api!=null && api!="" ){ //urlApis= JSON.parseObject(api, List.class); // System.out.println("缓存中"+urlApis); // return urlApis; urlApis= JSON.parseArray(api, Api.class); System.out.println(urlApis); return urlApis; } //获取该用户的api权限 List<Api> apis = userService.getApiUrlByUserName(username); //加入缓存然后设置过期时间为半个小时 redisUtil.set(key,JSON.toJSONString(apis),1800); //redisTemplate.opsForValue().set(key, JSON.toJSONString(apis), Duration.ofSeconds(1800L)); return apis; } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
  • 相关阅读:
    Python课程设计之俄罗斯方块
    Nginx限流熔断
    从零开始的搭建指南:开发高效的抖音预约服务小程序
    Science:“消除噪音”量子比特实现了纠错的重大突破
    内网安全【2】——域防火墙/入站出站规则/不出网隧道上线/组策略对象同步
    Day38.动规:斐波那契、爬楼梯、最小代价爬楼梯
    在C++中++a和a++有什么区别?
    【C语言初阶】switch语句的基本语法
    一个颜值功能双在线的Zookeeper可视化工具
    Java面试题-Java核心基础-第三天(基本数据类型)
  • 原文地址:https://blog.csdn.net/qq_49137582/article/details/126333464