zoukankan      html  css  js  c++  java
  • 使用SpringSecurity方法授权,连接数据库做权限管理

    SecurityConfig

    package com.jay.SpringBootStudy8.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    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.config.http.SessionCreationPolicy;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.provisioning.InMemoryUserDetailsManager;
    
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)//方法授权
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        //用数据库查询的话,就不需要在这里模拟用户了
    //    @Bean
    //    public UserDetailsService userDetailsService(){
    //        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    //        manager.createUser(User.withUsername("user2").password("123456").authorities("add","delete","update").roles("vip1").build());
    //        manager.createUser(User.withUsername("user3").password("123456").authorities("add","delete","update").roles("vip2").build());
    //        return  manager;
    //    }
    
        //密码编码器
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
        //认证
    //    @Override
    //    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //        super.configure(auth);
        //BCryptPasswordEncoder 加密方式,用户名admin、密码123456,可以and()连接多个
    //        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
    //                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
    //                .and()
    //                .withUser("user1").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2")
    //        ;
    //    }
    
        //授权
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            //Security 创建 Session,使用Session保持会话,如果使用 jwt Token,则可以设置成STATELESS,不生成也不是用Session
            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
            //使用方法授权,不需要下面的web授权配置
            //功能页只有具有权限的人才能访问
    //        http.authorizeRequests()
    //                .antMatchers("/level1").hasRole("vip1")
    //                .antMatchers("/level2").hasRole("vip2")
    //                .antMatchers("/level3").authenticated()
    //                .anyRequest().permitAll();
    
            //禁用csrf跨站
    //        <!--加上后不用禁用csrf-->
    //    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
    //        http.csrf().disable();
    
            //开启登录,定制登录页,自定义请求参数名 和 登录请求地址。
            //如果不自定义登录请求地址,那登录form的action需要是loginPage指定的地址 /userLogin
            http.formLogin().loginPage("/userLogin")
                    .usernameParameter("name")
                    .passwordParameter("pwd")
                    .loginProcessingUrl("/userLogin")
                    .successForwardUrl("/level1")
            ;
            //记住我,自定义请求参数
            http.rememberMe().rememberMeParameter("remember");
            //注销、删除cookie、清除session、跳转登录页
            http.logout().deleteCookies("remove").invalidateHttpSession(true).logoutSuccessUrl("/userLogin");
        }
    }
    

    SpringDataUserDetailsService

    package com.jay.SpringBootStudy8.config;
    
    import com.jay.SpringBootStudy8.pojo.Permission;
    import com.jay.SpringBootStudy8.pojo.Role;
    import com.jay.SpringBootStudy8.pojo.SysUser;
    import com.jay.SpringBootStudy8.service.PermissionService;
    import com.jay.SpringBootStudy8.service.RoleService;
    import com.jay.SpringBootStudy8.service.SysUserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.userdetails.User;
    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.List;
    import java.util.stream.Collectors;
    
    @Service
    public class SpringDataUserDetailsService implements UserDetailsService {
    
        @Autowired
        private SysUserService sysUserService;
        @Autowired
        private RoleService roleService;
        @Autowired
        private PermissionService permissionService;
    
        //根据账户查询用户
        @Override
        public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
            System.out.println("userName:" + s);
            //连接数据库 123456 md5密码 efd9d1b8bfb00e8e3647990f7d74d1d8,BCrypt密码 $2a$10$bobysVYApzaZF2RhNcIQp.qum8V1e9jg5jkqStlRKkfXkB0y4P5AC
            SysUser user = sysUserService.getModelByUserName(s);
            if (user != null) {
                List<Role> roles = roleService.getAllByUserId(user.getId());
                List<String> roleNames = roles.stream().map(Role::getName).collect(Collectors.toList());
                List<Integer> roleIds = roles.stream().map(Role::getId).collect(Collectors.toList());
                List<Permission> permissions = permissionService.getAllByRoleIds(roleIds);
                List<String> permissionCodes = permissions.stream().map(Permission::getCode).collect(Collectors.toList());
                User.UserBuilder builder = User.withUsername(user.getUserName()).password(user.getPwd());
                builder.authorities(permissionCodes.toArray(new String[0]));
    //            builder.roles(roleNames.toArray(new String[0]));//roles会替换authorities的赋值
                UserDetails userDetails = builder.build();
                return userDetails;
            }
            return null;
        }
    }
    

     Controller》Action

    @RequestMapping("/level1")
        @PreAuthorize("hasAuthority('users:mgr')")//方法授权,方法执行前校验,建议使用
        public String level1(Model model) {
            //得到当前认证通过的用户身份,用户的信息都在这里存着
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();//用户权限
            Object credentials = authentication.getCredentials();//用户凭证
            Object details = authentication.getDetails();//用户详细信息
            Object principal = authentication.getPrincipal();//用户身份
            UserDetails userDetails = (UserDetails) principal;
            String userName = userDetails.getUsername();
            model.addAttribute("userName",userName);
            return "views/level1/1";
        }
    

     前端:

    <!DOCTYPE html>
    <html lang="en_US" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>login</title>
    </head>
    <body>
    <h1>login</h1>
    <a th:href="@{/logout}">注销</a>
    <a th:href="@{/userLogin}">login</a>
    <p th:text="${msg}" style="color: red;"></p>
    <form method="post" th:action="@{/userLogin}">
        <!--加上后不用禁用csrf-->
        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
        name:<input type="text" name="name"/>
        <br/>
        pwd:<input type="password" name="pwd"/>
        <br/>
        <input type="checkbox" name="remember"/>Remember Me
        <br/>
        <button type="submit">submit</button>
    </form>
    </body>
    </html>
    

    视频:https://www.bilibili.com/video/BV1VE411h7aL?p=25

  • 相关阅读:
    Java之冒泡完整理解
    Java 之数组的复制,
    python 小白之路(跳动的球)
    小白之旅,Python运算符
    在学习枯燥的Java中遇见美丽的Jframe,窗体中的单选按钮(JRadioButton)
    自定义的无数据提示界面
    北京地铁站经纬度集合(包含大部分)
    自定义UItextFiled,限制TextFiled 的输入长度
    消息发送机制的利用
    app 后台持续定位
  • 原文地址:https://www.cnblogs.com/xsj1989/p/15347426.html
Copyright © 2011-2022 走看看