zoukankan      html  css  js  c++  java
  • Spring Security 简单实现

    Spring Security(官网地址:https://spring.io/projects/spring-security)是Spring家族的安全框架

    依赖配置

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

    SecurityConfig

    使用Spring Security进行安全管理需要使SecurityConfig继承WebSecurityConfigurerAdapter类,并且使用HttpSecurity的一些安全策略进行配置。

    • authorizeRequests:配置一些资源或链接的权限认证。

    • antMatchers:配置哪些资源或链接需要被认证。

    • permitAll:设置完全允许访问的资源和链接。

    • hasRole:配置需要认证的资源或链接的角色。需要注意,若这里需要配置权限为USER,则用户需要拥有权限ROLE_USER,这就是初始化脚本中权限内容修改的原因。

    • formLogin:设置form表单提交配置。

    • loginPage:设置一个自定义的登录页面URL。

    • failureUrl:设置一个自定义的登录失败的URL。

    • successForwardUrl:设置一个登录成功后自动跳转的URL。

    • accessDeniedPage:设置拒绝访问的URL。

    • logoutSuccessUrl:设置退出登录的URL。

    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private RoleRepository roleRepository;
        @Autowired
        private MyUserDetailsService myUserDetailsService;
    
        @Override
        protected void configure(HttpSecurity httpSecurity) throws Exception {
            //配置资源文件 其中/css/**,/index可以任意访问,/select需要USER权限,/delete需要ADMIN权限
            httpSecurity
                    .authorizeRequests()
                    .antMatchers("/css/**", "/index").permitAll()
                    .antMatchers("/select").hasRole("USER")
                    .antMatchers("/delete").hasRole("ADMIN");
            //动态加载数据库中角色权限
            List<Role> roleList = roleRepository.findAll();
            for (Role role : roleList) {
                List<Menu> menuList = role.getMenuList();
                for (Menu menu : menuList) {
                    //在SpringSecurity校验权限的时候,会自动将权限前面加ROLE_,所以我们需要 将我们数据库中配置的ROLE_截取掉。
                    String roleName = role.getRoleName().replace("ROLE_", "");
                    String menuName = "/" + menu.getMenuName();
                    httpSecurity
                            .authorizeRequests()
                            .antMatchers(menuName)
                            .hasRole(roleName);
                }
            }
            //配置登录请求/login 登录失败请求/login_error 登录成功请求/
            httpSecurity
                    .formLogin()
                    .loginPage("/login")
                    .failureUrl("/login_error")
                    .successForwardUrl("/");
            //登录异常,如权限不符合 请求/401
            httpSecurity
                    .exceptionHandling().accessDeniedPage("/401");
            //注销登录 请求/logout
            httpSecurity
                    .logout()
                    .logoutSuccessUrl("/logout");
        }
    
        @Bean
        public static NoOpPasswordEncoder passwordEncoder() {
            return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
        }
    
    
        //根据用户名密码实现登录
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
            authenticationManagerBuilder
                    .inMemoryAuthentication()
                    //.passwordEncoder(new BCryptPasswordEncoder())
                    .withUser("test").password("123").roles("USER")
                    .and()
                    .withUser("admin").password("123").roles("ADMIN", "USER");
            authenticationManagerBuilder.userDetailsService(myUserDetailsService);
        }
    }

    MyUserDetailsService

    使用数据库认证用户需要自定义一个类来实现UserDetailsService重写loadUserByUsername方法进行认证授权

    @Service
    public class MyUserDetailsService implements UserDetailsService {
        @Autowired
        private UserRepository userRepository;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userRepository.findByUserName(username);
            if (user == null) {
                throw new UsernameNotFoundException("用户不存在!");
            }
            List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>();
            for (Role role : user.getRoleList()) {
                simpleGrantedAuthorities.add(new SimpleGrantedAuthority(role.getRoleName()));
            }
            return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getPassWord(), simpleGrantedAuthorities);
        }
    }

    Controller

    @Controller
    @Api(tags = "TestSecurityController")
    public class TestSecurityController {
    
        private static final Logger log = LoggerFactory.getLogger(TestSecurityController.class);
    
        @RequestMapping({"/", "/index"})
        public String index() {
            return "index";
        }
    
        @RequestMapping("/select")
        public String select() {
            return "select";
        }
    
        @RequestMapping("/delete")
        public String delete() {
            return "delete";
        }
    
        @RequestMapping("/login")
        public String login() {
            return "login";
        }
    
        @RequestMapping("/login_error")
        public String login_error(Model model) {
            model.addAttribute("login_error", "用户名或密码错误");
            return "login";
        }
    
        @RequestMapping("/logout")
        public String logout(Model model) {
            model.addAttribute("login_error", "注销成功");
            return "login";
        }
    
        @RequestMapping("/401")
        public String error() {
            return "401";
        }
    }

    参考来源:Spring Boot 2实战之旅-7.2 使用Spring Security

    源码:https://gitee.com/caoyeoo0/xc-springboot/tree/springSecurity/

  • 相关阅读:
    面向对象静态语言的模型
    语言的静态分析技术
    面向对象的核心元素与机制
    Lua 笔记
    Linux配置系统
    Linux文件类型
    Wijmo 日历插件
    窗外大雨,心里小雨
    一次胆战心惊的服务器经历
    一次胆战心惊的服务器经历
  • 原文地址:https://www.cnblogs.com/ooo0/p/14025648.html
Copyright © 2011-2022 走看看