基于SpringSecurity实现权限控制(学习记录)

pom文件

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        //前后端分离可以不用引下面的thymeleaf
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>

在前后端不分离使用thymeleaf,会有一个默认的登录,第一次弄的时候找了半天没找出来这个页面在哪里cao

Config配置类

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 用来定义哪些请求需要忽略安全控制,哪些请求必须接受安全控制;还可以在合适的时候清除SecurityContext以避免内存泄漏,
     * 同时也可以用来定义请求防火墙和请求拒绝处理器,另外我们开启Spring Security Debug模式也是这里配置的
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        //super.configure(web);
        web.ignoring()
                .antMatchers("/js/**",
                        "/assets/**","/data/**","/files/**"
                        ,"/fonts/**","/lib/**","/plugins/**","/resources/**"
                        ,"/vendors/**",
                        "/css/**", "/images/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);


        http.formLogin()
                //登录页面在static中直接xx.html,在thmplates中需要controller请求返回
                .loginPage("/user/tologin").permitAll()
//                .loginPage("/myLogin.html").permitAll()
                //指登录成功后,是否始终跳转到登录成功url。它默认为false
                .defaultSuccessUrl("/user/dologin", true)
//                //post登录接口,登录验证由系统实现
                .loginProcessingUrl("/user/login")
                //用户密码错误跳转接口
                .failureUrl("/error.html")
                //要认证的用户参数名,默认username,自定义登录逻辑,对应html中的name
                .usernameParameter("username")
                //要认证的密码参数名,默认password
                .passwordParameter("password")
                //配置注销
                .and()
          .logout()
                //自定义注销接口
                .logoutUrl("/logout")
                //注销成功后跳转到的接口
                .logoutSuccessUrl("/user/tologin").permitAll()
                //删除自定义的cookie
                .deleteCookies("token");
        //3.进一步配置自定义的登录页面
        //拦截请求,创建FilterSecurityInterceptor
        http.authorizeRequests()
                .antMatchers("/user/tologin/**","/user/usermessage","/user/toeditmember","/user/password").permitAll()
                .antMatchers("/user/dologin","/user/paySuccess").permitAll()
                .antMatchers("/user/toindex","/notice/transaction","/notice/toPay","/notice/toPay1","/notice/toLogistics","/notice/secondReg").permitAll()
                .antMatchers("/user/e","/user/exportAccount").hasAuthority("admin")
                .antMatchers("/user/doregister","/user/toregister").permitAll()
                .antMatchers("/notice_cy/unnoticeable","notice_cy/Notify_editor","user/companymessage","/user/docompanymessage").hasAuthority("admin")
                .antMatchers("/notice/qgcheck","/notice/spqg","notice_cy/Notify_editor","user/companymessage","/user/buyercenter","/user/dozhaipai2").hasAuthority("buyer")
                .antMatchers("/notice/gpcheck","/notice/gp","notice_cy/Notify_editor","user/companymessage","/user/sellercenter","/user/dozhaipai1").hasAuthority("seller")
                .antMatchers("/order/alipay").permitAll()
                .antMatchers("/notice/admin","/user/dousermessage/**",
                        "/user/password/**"
                ).hasAuthority("admin")
                //访问权限控制
//                .antMatchers("/error.html").hasAuthority("vip1")
//                .antMatchers("/main1.html").hasAnyAuthority("adMin","admiN")
//                .antMatchers("/main1.html").hasRole("abc")
                //访问静态资源,约定请求格式
//                .antMatchers(HttpMethod.POST,"/images/**").permitAll()
                //除以上的请求不拦截外其他任何请求都必须被认证
                .anyRequest().authenticated()
                //用and来表示配置过滤器结束,以便进行下一个过滤器的创建和配置
                .and()
                //设置表单登录,创建UsernamePasswordAuthenticationFilter

                //注意:需禁用crsf防护功能,否则登录不成功
                .csrf().disable()
                .headers().frameOptions().disable();



    }
    @Bean
    public PasswordEncoder getPw(){
        return new BCryptPasswordEncoder();
    }
}

自定义登录逻辑

设置了自定义登录请求后将走自定义登录逻辑,而不走Controller了

@Service
public class UserServicedetail implements UserDetailsService {
    @Autowired
    private PasswordEncoder pw;

    @Autowired
    private UserService userService;

    public static Account account=new Account();
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        account =userService.getuserbyname(username);
        if (account==null) {
            throw new UsernameNotFoundException("用户名不存在");
        }

        //1.查询数据库判断用户名是否存在,如果不存在抛出
        String password = pw.encode(account.getPassword());
        System.out.println(account.getRole());
        switch (account.getRole())
        {
            //2.把查询出来的密码(注册时已经加密过)进行解析,或直接把密码放入构造方法
            //赋权
            case 1:{
                System.out.println(username+account.getPassword()+"赋予了admin权限");
                return new User(username,password,
                        AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal,ROLE_abc"));
            }
            case 2:{
                System.out.println(username+account.getPassword()+"赋予了buyer权限");
                return new User(username,password,
                        AuthorityUtils.commaSeparatedStringToAuthorityList("buyer"));
            }
            case 3:{
                System.out.println(username+account.getPassword()+"赋予了seller权限");
                return new User(username,password,
                        AuthorityUtils.commaSeparatedStringToAuthorityList("seller"));
            }
            default:
                return new User(username,password,
                        AuthorityUtils.commaSeparatedStringToAuthorityList(""));
        }

    }
}

使用thymeleaf引入权限控制

html的命名空间加入

<html xmlns:th="http://www.thymeleaf.org"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">

后台管理系统大多都是一个模板,但要针对不同的用户,如果制作多套页面按权来返回的话,感觉不太好,因此直接在一个页面上引入多个功能

在这里插入图片描述
这里是侧滑栏,求购审核和商品挂牌是在同一个页面,但不同权限的人只能看到属于它权限的东西

需要这两HttpServletRequest request, HttpServletResponse response

jwt创建和解析token

public class jwt {

    public String  testCreatTokenByClaims(String username,String password) {
//当前系统时间的长整型
        long now = System.currentTimeMillis();
//过期时间,这里是60分钟后的时间长整型
        long exp = now + 60 * 1000*60*24;
//创建一个JwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
//声明的标识{"jti":"888"}
                .setId("888")
//主体,用户{"sub":"Rose"}
                .setSubject("Rose")
//创建日期{"ita":"yjxxtxx"}
                .setIssuedAt(new Date())
//签名手段,参数1:算法,参数2:盐
                .signWith(SignatureAlgorithm.HS256, "yjxxt")
//设置过期时间
                .setExpiration(new Date(exp))
//直接传入map
// .addClaims(map)
                .claim("username",username)
                .claim("password",password)
                .claim("roles","admin");
//获取jwt的token
       String token = jwtBuilder.compact();
        System.out.println(token);
        return token;
    }

    public Map<String, String> testParseTokenByClaims(String token) {
//token

//解析token获取负载中的声明对象
        Claims claims = Jwts.parser()
                .setSigningKey("yjxxt")
                .parseClaimsJws(token)
                .getBody();
        Map<String,String > userMap=new HashMap<>();
//打印声明的属性
        System.out.println("id:" + claims.getId());
        System.out.println("subject:" + claims.getSubject());
        System.out.println("issuedAt:" + claims.getIssuedAt());
        DateFormat sf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("签发时间:"+sf.format(claims.getIssuedAt()));
        System.out.println("过期时间:"+sf.format(claims.getExpiration()));
        System.out.println("当前时间:"+sf.format(new Date()));
        System.out.println("roles:"+claims.get("roles"));
        userMap.put("username", claims.get("username").toString());
        userMap.put("password", claims.get("password").toString());
        userMap.put("roles", claims.get("roles").toString());
        return userMap;
    }

把token存到浏览器

        jwt jwt=new jwt();
        String token=jwt.testCreatTokenByClaims(username,account.getPassword());
        Cookie cookie=new Cookie("token","cookievalue");
        cookie.setMaxAge(60 * 1000*60*24);
        cookie.setPath("/");
        cookie.setValue(token);
        response.addCookie(cookie);

查看本地的cookies

        Cookie rcookie = null;
        Cookie[] cookies=request.getCookies();
        for (Cookie x:cookies) {
            if(x.getName().equals("token"))
            {
                rcookie=x;
                System.out.println("存在"+rcookie.getName()+" "+rcookie.getValue());
                break;
            }
        }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值