zoukankan      html  css  js  c++  java
  • 微服务迁移记(五):WEB层搭建(2)-SpringSecurity集成

    一、redis搭建

    二、WEB层主要依赖包

    三、FeignClient通用接口

    以上三项,参考《微服务迁移记(五):WEB层搭建(1)

    接下来,集成SpringSecruity,实现用户登录。

    总体思路为:自定义UserDetails、UserDetailsService,重载WebSecurityConfigurerAdapter实现自定义表单登录,将菜单和按钮权限也扔到SpringSecruity的Session里。

    四、SpringSecurity集成

    1. 自定义MyUserDetails,实现UserDetails接口

    1)我在里面多定义了一个UserEntity实体,通过get方法可以拿到这个实体,实现前台的一些业务逻辑。

    RoleTreefuncEntity是功能权限树,也扔到session里。

    2)isAccountNonExpired、isAccountNonLocked、isCredentialsNonExpired、isEnabled这几个方法,因为我直接从用户表取 del_flag=0的用户,不判断用户禁用或过期等状态,都直接返回true了。

    package com.zyproject.web.secrity;
    
    import com.zyproject.entity.RoleTreefuncEntity;
    import com.zyproject.entity.UserEntity;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    
    import java.util.Collection;
    import java.util.List;
    
    /**
     * @program: zyproject
     * @description: 实现SpringSercrity UserDetails
     * @author: zhouyu(zhouyu629 # qq.com)
     * @create: 2020-02-12
     **/
    public class MyUserDetails implements UserDetails {
    
        private UserEntity userEntity; //用户实体
        //将用户所有的角色菜单权限放到内存中,供校验使用
        private List<RoleTreefuncEntity> roleTreefuncEntities;
    
        public MyUserDetails(UserEntity userEntity,List<RoleTreefuncEntity> roleTreefuncEntities){
            this.userEntity = userEntity;
            this.roleTreefuncEntities = roleTreefuncEntities;
        }
    
        //获取用户真实姓名
        public String getRealName(){
            return userEntity.getUser_name();
        }
    
        //获取用户实体
        public UserEntity getUserEntity(){
            return this.userEntity;
        }
    
        //获取权限菜单
        public List<RoleTreefuncEntity> getTreefuncEntities(){return this.roleTreefuncEntities;}
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return null;
        }
    
        @Override
        public String getPassword() {
            return userEntity.getLogin_password();
        }
    
        @Override
        public String getUsername() {
            return userEntity.getLogin_code();
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
    
        @Override
        public boolean isEnabled() {
            return true;
        }
    }

     2. 自定义MyUserDetailsService接口,实现UserDetailsService接口

    package com.zyproject.web.secrity;
    
    import com.google.gson.Gson;
    import com.zyproject.common.CodeEnum;
    import com.zyproject.common.ResponseData;
    import com.zyproject.entity.RoleTreefuncEntity;
    import com.zyproject.entity.UserEntity;
    import com.zyproject.web.service.TreeService;
    import com.zyproject.web.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    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.Arrays;
    import java.util.List;
    
    /**
     * @program: zyproject
     * @description: 实现SpringSecrity UserDetailService接口
     * @author: zhouyu(zhouyu629 # qq.com)
     * @create: 2020-02-12
     **/
    @Service
    public class MyUserDetailService implements UserDetailsService {
        @Autowired
        private UserService userService;
        @Autowired
        private TreeService treeService;
    
        @Override
        public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
            ResponseData<UserEntity> userResult = userService.findByLoginname(s);
            UserEntity user = new UserEntity();
            if(userResult.getCode() == CodeEnum.SUCCESS.getCode()){
                user = userResult.getData(UserEntity.class);
                ResponseData rightResult = treeService.getRoleTreefuncByUserid(user.getUser_id());
                Gson gson = new Gson();
                List<RoleTreefuncEntity> roleTreefuncEntities = Arrays.asList(gson.fromJson(gson.toJson(rightResult.getData()),RoleTreefuncEntity[].class));
                return new MyUserDetails(user,roleTreefuncEntities);
            }else{
                throw new UsernameNotFoundException(s);
            }
        }
    }

    3. SecurityConfiguration配置

    1) 覆写protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder),实现MD5密码校验

    2) protected  void configure(HttpSecurity httpSecurity),实现自定义表单登录

    package com.zyproject.web.secrity;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    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.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    /**
     * @program: zyproject
     * @description: SpringSercrity配置
     * @author: zhouyu(zhouyu629 # qq.com)
     * @create: 2020-02-12
     **/
    @Configuration
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private MyUserDetailService myUserDetailService;
    
        @Autowired
        private MyAuthenctiationFailureHandler myAuthenctiationFailureHandler;
    
        @Autowired
        private MyAuthenctiationSucessHandler myAuthenctiationSucessHandler;
    
        @Override
        protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
            authenticationManagerBuilder.userDetailsService(myUserDetailService).passwordEncoder(new PasswordEncoder() {
                @Override
                public String encode(CharSequence charSequence) {
                    return MD5Util.encode((String)charSequence);
                }
    
                @Override
                public boolean matches(CharSequence charSequence, String s) {
                    return s.equals(MD5Util.encode((String)charSequence));
                }
            });
        }
    
    
        @Override
        protected  void configure(HttpSecurity httpSecurity) throws Exception{
            httpSecurity.headers().frameOptions().disable();
            httpSecurity
                    .authorizeRequests()
                    .antMatchers("/manage/error","/manage/login/**","/manage/login-submit","/manage/images/**","/manage/js/**","/manage/css/**","/manage/fonts/**").permitAll()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin()
                    //指定登录路径
                    .loginPage("/manage/login")
                    .loginProcessingUrl("/manage/login-submit") //表单请求的路径,貌似无用,已经在config里做密码校验了
                    .failureHandler(myAuthenctiationFailureHandler)
                    .successHandler(myAuthenctiationSucessHandler)
                    .failureUrl("/manage/error?key=1002")
                    .defaultSuccessUrl("/manage/index")
                    .usernameParameter("username")
                    .passwordParameter("password")
                    //必须允许所有用户访问我们的登录页(例如未验证的用户,否则验证流程就会进入死循环)
                    .permitAll()
                    .and()
                    .sessionManagement()
                    .invalidSessionUrl("/manage/error?key=timeout");
            //默认都会产生一个hiden标签 里面有安全相关的验证 防止请求伪造 这边我们暂时不需要 可禁用掉
            httpSecurity.csrf().disable();
        }
    
        @Override
        public void configure(WebSecurity webSecurity) throws Exception{
            super.configure(webSecurity);
        }
    }

    五、FreeMarker集成

    待续

    六、权限管理

    待续

  • 相关阅读:
    2017.0710.《计算机组成原理》-信息的校验
    2017.0707.《计算机组成原理》-汉明码
    2017.0706.《计算机组成原理》-存储器的校验
    基于mpvue的小程序项目搭建的步骤一
    微信小程序图片使用示例
    如何给小程序页面加载一张背景图片
    【组件】微信小程序input搜索框的实现
    基于cropper.js的图片上传和裁剪
    经典小程序源码及其下载地址
    【前端切图】用css画一个卡通形象-小猪佩奇
  • 原文地址:https://www.cnblogs.com/zhouyu629/p/12348798.html
Copyright © 2011-2022 走看看